diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..be6d63e5d2 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +github: mapstruct +open_collective: mapstruct diff --git a/.github/INCIDENT_RESPONSE.md b/.github/INCIDENT_RESPONSE.md new file mode 100644 index 0000000000..139ee6cdb3 --- /dev/null +++ b/.github/INCIDENT_RESPONSE.md @@ -0,0 +1,134 @@ +# MapStruct Incident Response Plan + +This document is the playbook MapStruct maintainers follow when an incident is active. It is not a replacement for ordinary bug triage — regular contributions and bug reports still flow through the process described in [`CONTRIBUTING.md`](../CONTRIBUTING.md). For instructions on how to *report* a security vulnerability, see [`SECURITY.md`](../SECURITY.md). + +MapStruct is a compile-time Java annotation processor distributed via Maven Central. The incidents this plan covers reflect that reality: immutable published artifacts, a manual release workflow, and a small maintainer team. There is no running service to page someone about at 3am. + +## What counts as an incident + +Four categories, with a concrete MapStruct-flavored example of each: + +* **Security vulnerability / CVE** — e.g. a crafted `@Mapper` input triggers arbitrary code execution in the annotation processor during `javac`, or the generated code contains an injection vulnerability. +* **Critical bug breaking user builds** — e.g. a released `1.x.y` generates non-compiling code for all users of `@Mapping`, with no workaround short of pinning to the previous version. +* **Release / supply-chain issue** — e.g. a bad artifact reaches Maven Central, a release secret is leaked, or `release.yml` fails mid-publish after already pushing version-bump commits to `main`. +* **Infra / CI incident** — e.g. a GitHub Actions workflow blocks all PRs, CodeQL flags a real finding, or the mapstruct.org website is out of sync after a release. + +Ordinary user bugs filed as issues are *not* incidents — they follow the normal contribution flow. + +## Severity levels + +| Severity | Definition | MapStruct example | +|---|---|---| +| **SEV-0** | Active exploitation or supply-chain compromise of a published artifact; users must stop using a version immediately. | Compromised signed JAR on Maven Central; leaked GPG or Sonatype credentials with evidence of misuse; RCE in the annotation processor triggered during `javac`. | +| **SEV-1** | Released version is broken for a majority of users or contains an undisclosed security flaw with no workaround. | A `1.x.y` release generates non-compiling code for all users of `@Mapping`; confirmed CVE with CVSS ≥ 7 but not yet exploited. | +| **SEV-2** | Released version broken for a specific but significant cohort; workaround exists; or lower-severity CVE; or the release pipeline is blocked. | Regression affecting only Java 21 + records; CVE with CVSS < 7; JReleaser fails staging so a release is blocked but nothing published; CI red on `main`. | +| **SEV-3** | Degraded but not blocking. | CodeQL false-positive noise; a single OS matrix leg flaky; mapstruct.org docs out of sync post-release. | + +## General response flow + +Every incident follows the same six-step spine, regardless of category: + +1. **Acknowledge** — confirm the report has been received and is being looked at. +2. **Assess severity** — assign SEV-0 / SEV-1 / SEV-2 / SEV-3 using the table above. +3. **Declare** — open the tracking artifact (GitHub Security Advisory for security issues, pinned issue for regressions, Discussion thread for CI incidents). +4. **Mitigate** — give users a workaround, yank a bad release, or disable a broken workflow — whatever stops the immediate bleeding. +5. **Fix and verify** — land the real fix, add a regression test, cut a patch release if needed, verify the fix on the published artifact. +6. **Close out** — announce resolution on the public channels, credit reporters, update this document if the process needs changing. + +The playbooks below are specializations of this spine. + +## Playbooks + +### A. Security vulnerability / CVE + +1. Acknowledge receipt within 48 hours via GitHub Private Vulnerability Reporting. +2. Confirm reproducibility against the latest release and `main`; assign a CVSS score. +3. Open a **draft GitHub Security Advisory (GHSA)** — this is the tracking artifact. Do **not** open a public issue. +4. Request a CVE via the GHSA (GitHub auto-requests from MITRE). +5. Develop the fix on the private fork the advisory creates; maintainers review before merge. +6. Merge the private-fork fix into `main` using the "Merge" button on the advisory page; confirm CI is green on `main` before proceeding. +7. Coordinate a disclosure date with the reporter — target ≤ 90 days from report, sooner for SEV-0. +8. Add a `### Security` entry to `NEXT_RELEASE_CHANGELOG.md`, then cut a patch release from `main`; verify the GPG signature and checksums on the published artifact before publishing the advisory. +9. Publish the GHSA, announce on Discussions + mapstruct.org blog, and credit the reporter unless they decline. + +### B. Critical bug breaking user builds + +1. Reproduce the bug against the reported version using a minimal `@Mapper` (ideally in `integrationtest/`). +2. Use `git bisect` across tagged releases to find the introducing commit. +3. Open a pinned GitHub issue titled `[REGRESSION ] ...`, labeled `regression` and `priority:critical`. +4. Post a user-facing workaround (e.g. pin `` to the prior release) in the issue within 24 hours. +5. Decide between a patch release or a revert-only fix. For SEV-1, target a patch release within 72 hours. +6. Add a regression test in `processor/src/test/` that locks the behavior. +7. Update `NEXT_RELEASE_CHANGELOG.md` under `### Bugs`, run the `release.yml` workflow dispatch, verify the artifact lands on Central before closing the issue. +8. Announce on Discussions; link from the pinned issue. + +### C. Release / supply-chain issue + +1. **Stop the bleeding** — if `release.yml` is still running, cancel the run from the Actions UI immediately. +2. Assess blast radius: did artifacts reach Maven Central staging only, Central itself, or also the mapstruct.org website? +3. If any secret is suspected compromised, rotate **before** taking any other recovery action: `GPG_PASSPHRASE`, `GPG_PUBLIC_KEY`, `GPG_PRIVATE_KEY`, `SONATYPE_USERNAME`, `SONATYPE_PASSWORD`, `SONATYPE_CENTRAL_USERNAME`, `SONATYPE_CENTRAL_TOKEN`, `GIT_WEBSITE_ACCESS_TOKEN`. Revoke the GPG key via a public keyserver. Rotate in this order: **Sonatype first** (stops further publishes), **GPG second** (revoke publicly), **website PAT last** — see the rotation order guidance in the **Secrets and rotation** section below. +4. If a bad artifact reached Maven Central: **you cannot delete it.** Publish a superseding version immediately (e.g. `1.6.4` to replace a bad `1.6.3`), and mark the bad version yanked via the **Yanked-release procedure** section below. +5. If `main` was corrupted (stray version bump, bad tag): revert commits, recreate the tag, coordinate any force-push with maintainers' explicit agreement. +6. If the website push succeeded but the release failed: manually revert the corresponding commit on the `mapstruct/mapstruct.org` repo. +7. Open a SEV-0 or SEV-1 tracking issue; freeze further releases until the root cause is known. +8. Replay the release from a clean state, verifying signatures at each step, then announce the yank on Discussions and mapstruct.org. + +### D. Infra / CI incident + +1. Identify scope: single workflow (e.g. `windows.yml`), all workflows, or a GitHub Actions-wide outage. +2. Check [githubstatus.com](https://www.githubstatus.com) — if the cause is upstream, park and monitor. +3. If it is our bug: open an issue labeled `ci`, and disable the affected workflow (comment the `on:` block or gate with `if: false`) to unblock contributors. +4. If contributor PRs are blocked for more than 4 hours, post a status update in Discussions. +5. Root-cause. Common suspects: action version drift, JDK EA breakage, Maven cache corruption, CodeQL rule updates. +6. Fix in a focused PR; require a green run on a throwaway branch before merging. +7. Re-enable the workflow. +8. Escalate to SEV-1 only if the incident is blocking a pending release. + +## Yanked-release procedure + +Maven Central is **immutable**: once an artifact is published, it cannot be deleted. When a release must be withdrawn, this is the procedure: + +1. Publish a superseding version (e.g. `1.6.4` to replace a bad `1.6.3`) as soon as a fix or clean rebuild is ready. +2. If the yank is security-related, open or update the corresponding GitHub Security Advisory (GHSA) for the bad version — the GHSA is the machine-readable record of the security flaw. For non-security yanks (e.g. a broken build regression), skip this step; the `readme.md` banner and blog post (steps 3–4) are the durable record. +3. Add a short banner to `readme.md` listing the yanked version, the reason, and the replacement — e.g. *"⚠ MapStruct 1.6.3 is yanked due to [reason]. Please upgrade to 1.6.4."* +4. Post a notice on the mapstruct.org blog and link it from Discussions. +5. Remove the banner from `readme.md` at the next normal release cycle (the GHSA, if opened, is the durable record for security yanks; the blog post is the durable record for non-security yanks). + +## Secrets and rotation + +The IRP itself does not store any secret. This section is the **index** of which secrets drive releases and CI, so that a rotation during an incident hits everything in one pass. The live rotation credentials and step-by-step procedures live outside the repo in the maintainers' password manager. + +Secrets used by `.github/workflows/release.yml`: + +| Secret | Purpose | Rotation path | +|---|---|---| +| `GPG_PASSPHRASE` | Passphrase for the release signing key | Change on a local keyring, update the repo secret, import new passphrase | +| `GPG_PUBLIC_KEY` | ASCII-armored public key for JReleaser | Re-export from local keyring after rotation | +| `GPG_PRIVATE_KEY` | ASCII-armored private key for JReleaser | Generate new key pair, re-export, revoke old key via keyserver | +| `SONATYPE_CENTRAL_USERNAME` | New Sonatype Central Portal username | Rotate token in Sonatype Central Portal | +| `SONATYPE_CENTRAL_TOKEN` | New Sonatype Central Portal token | Rotate token in Sonatype Central Portal | +| `SONATYPE_USERNAME` | Legacy OSSRH / Nexus2 username | Rotate in Sonatype JIRA / legacy portal | +| `SONATYPE_PASSWORD` | Legacy OSSRH / Nexus2 password | Rotate in Sonatype JIRA / legacy portal | +| `GIT_WEBSITE_ACCESS_TOKEN` | PAT for pushing to `mapstruct/mapstruct.org` | Regenerate PAT on the owning account, update repo secret | + +Secrets used by `.github/workflows/main.yml`: + +| Secret | Purpose | Rotation path | +|---|---|---| +| `SONATYPE_USERNAME` / `SONATYPE_PASSWORD` | Snapshot deploys to OSSRH from `main` | Same as above | +| `CODECOV_TOKEN` | Upload coverage to Codecov | Regenerate on codecov.io, update repo secret | + +Rotation order during a suspected compromise: **Sonatype first** (to stop any further publish), **GPG second** (revoke key publicly), **website PAT last** (lowest blast radius). + +## Communication channels map + +| Incident type | Private tracking | Public acknowledgement | Resolution announcement | +|---|---|---|---| +| Security / CVE | GitHub Private Advisory | Only after the fix is released | GHSA publish + Discussion post + mapstruct.org blog | +| Critical bug | None (public) | Pinned GitHub issue within 24 hours | Issue closed + Discussion post | +| Release / supply chain | Direct maintainer DM (Signal) | Pinned issue + mapstruct.org banner | Discussion post + mapstruct.org blog | +| Infra / CI | None | Discussion thread if contributor-blocking | Close the discussion | + +## Maintenance of this document + +This document is reviewed annually and after every SEV-0 or SEV-1 incident. Changes are made via normal PRs. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000000..b6703e1800 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,45 @@ +name: Bug report +description: Create a report and help us improve +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + Please fill in all required fields with as many details as possible. + - type: textarea + id: expected + attributes: + label: Expected behavior + description: | + Describe what you were expecting MapStruct to do + placeholder: | + Here you can also add the generated code that you would like MapStruct to generate + - type: textarea + id: actual + attributes: + label: Actual behavior + description: | + Describe what you observed MapStruct did instead + placeholder: | + Here you can also add the generated code that MapStruct generated + - type: textarea + id: steps + attributes: + label: Steps to reproduce the problem + description: | + - Share your mapping configuration + - An [MCVE (Minimal Complete Verifiable Example)](https://stackoverflow.com/help/minimal-reproducible-example) can be helpful to provide a complete reproduction case + placeholder: | + Share your MapStruct configuration + validations: + required: true + - type: input + id: mapstruct-version + attributes: + label: MapStruct Version + description: | + Which MapStruct version did you use? + Note: While you can obviously continue using older versions of MapStruct, it may well be that your bug is already fixed. If you're using an older version, please also try to reproduce the bug in the latest version of MapStruct before reporting it. + placeholder: ex. MapStruct 1.5.2 + validations: + required: true diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..5b7ced86a4 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,16 @@ +contact_links: + - name: MapStruct Discussions + url: https://github.com/mapstruct/mapstruct/discussions + about: Please use the MapStruct GitHub Discussions for open ended discussions and to reach out to the community. + - name: Stack Overflow + url: https://stackoverflow.com/questions/tagged/mapstruct + about: For questions about how to use MapStruct, consider asking your question on Stack Overflow, tagged [mapstruct]. + - name: Documentation + url: https://mapstruct.org/documentation/stable/reference/html/ + about: The MapStruct reference documentation. + - name: Gitter Chat + url: https://gitter.im/mapstruct/mapstruct-users + about: For realtime communication with the MapStruct community, consider writing in our Gitter chat room. + - name: MapStruct Examples + url: https://github.com/mapstruct/mapstruct-examples + about: Some examples of what can be achieved with MapStruct. (contributions are always welcome) diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000000..191bba8345 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,43 @@ +name: Feature Request +description: Suggest an idea +body: + - type: markdown + attributes: + value: | + Please describe the use-case you have. This will better help us understand the context in which you're looking for a new feature. + - type: textarea + id: use-case + attributes: + label: Use case + description: | + Please describe the use-case you have. This will better help us understand the context in which you're looking for a new feature. + placeholder: Describe the use-case here + validations: + required: true + - type: textarea + id: solution + attributes: + label: Generated Code + description: | + Please describe the possible generated code you'd like to see in MapStruct generate. + Please note, it's not always easy to describe a good solution. Describing the use-case above is much more important to us. + placeholder: Describe the possible solution here. + validations: + required: false + - type: textarea + id: workarounds + attributes: + label: Possible workarounds + description: | + Please describe the possible workarounds you've implemented to work around the lacking functionality. + placeholder: Describe the possible workarounds here. + validations: + required: false + - type: input + id: mapstruct-version + attributes: + label: MapStruct Version + description: What MapStruct version and edition did you try? + placeholder: ex. MapStruct 1.5.2 + validations: + required: false diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..f6faee6938 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + groups: + github-actions: + patterns: + - "*" diff --git a/.github/scripts/update-website.sh b/.github/scripts/update-website.sh new file mode 100644 index 0000000000..7c92b8b43b --- /dev/null +++ b/.github/scripts/update-website.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# +# Copyright MapStruct Authors. +# +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 +# + +# env vars: +# VERSION +# GH_BOT_EMAIL + +# This script has been inspired by the JReleaser update-website.sh (https://github.com/jreleaser/jreleaser/blob/main/.github/scripts/update-website.sh) +set -e + +function computePlainVersion() { + echo $1 | sed 's/\([[:digit:]]*\)\.\([[:digit:]]*\)\.\([[:digit:]]*\).*/\1.\2.\3/' +} + +function computeMajorMinorVersion() { + echo $1 | sed 's/\([[:digit:]]*\)\.\([[:digit:]]*\).*/\1.\2/' +} + +function isStable() { + local PLAIN_VERSION=$(computePlainVersion $1) + if [ "${PLAIN_VERSION}" == "$1" ]; then + echo "yes" + else + echo "no" + fi +} + +STABLE=$(isStable $VERSION) +MAJOR_MINOR_VERSION=$(computeMajorMinorVersion $VERSION) + +DEV_VERSION=`grep devVersion config.toml | sed 's/.*"\(.*\)"/\1/'` +MAJOR_MINOR_DEV_VERSION=$(computeMajorMinorVersion $DEV_VERSION) +STABLE_VERSION=`grep stableVersion config.toml | sed 's/.*"\(.*\)"/\1/'` +MAJOR_MINOR_STABLE_VERSION=$(computeMajorMinorVersion $STABLE_VERSION) + +echo "📝 Updating versions" + +SEDOPTION="-i" +if [[ "$OSTYPE" == "darwin"* ]]; then + SEDOPTION="-i ''" +fi + +sed $SEDOPTION -e "s/^devVersion = \"\(.*\)\"/devVersion = \"${VERSION}\"/g" config.toml + +if [ "${STABLE}" == "yes" ]; then + sed $SEDOPTION -e "s/^stableVersion = \"\(.*\)\"/stableVersion = \"${VERSION}\"/g" config.toml + if [ "${MAJOR_MINOR_STABLE_VERSION}" != ${MAJOR_MINOR_VERSION} ]; then + echo "📝 Updating new stable version" + # This means that we have a new stable version and we need to change the order of the releases. + sed $SEDOPTION -e "s/^order = \(.*\)/order = 500/g" data/releases/${MAJOR_MINOR_VERSION}.toml + NEXT_STABLE_ORDER=$((`ls -1 data/releases | wc -l` - 2)) + sed $SEDOPTION -e "s/^order = \(.*\)/order = ${NEXT_STABLE_ORDER}/g" data/releases/${MAJOR_MINOR_STABLE_VERSION}.toml + git add data/releases/${MAJOR_MINOR_STABLE_VERSION}.toml + fi +elif [ "${MAJOR_MINOR_DEV_VERSION}" != "${MAJOR_MINOR_VERSION}" ]; then + echo "📝 Updating new dev version" + # This means that we are updating for a new dev version, but the last dev version is not the one that we are doing. + # Therefore, we need to update add the new data configuration + cp data/releases/${MAJOR_MINOR_DEV_VERSION}.toml data/releases/${MAJOR_MINOR_VERSION}.toml + sed $SEDOPTION -e "s/^order = \(.*\)/order = 1000/g" data/releases/${MAJOR_MINOR_VERSION}.toml +fi + +sed $SEDOPTION -e "s/^name = \"\(.*\)\"/name = \"${VERSION}\"/g" data/releases/${MAJOR_MINOR_VERSION}.toml +sed $SEDOPTION -e "s/^releaseDate = \(.*\)/releaseDate = $(date +%F)/g" data/releases/${MAJOR_MINOR_VERSION}.toml +git add data/releases/${MAJOR_MINOR_VERSION}.toml +git add config.toml + +echo "📝 Updating distribution resources" +tar -xf tmp/mapstruct-${VERSION}-dist.tar.gz --directory tmp +rm -rf static/documentation/${MAJOR_MINOR_VERSION} +cp -R tmp/mapstruct-${VERSION}/docs static/documentation/${MAJOR_MINOR_VERSION} +mv static/documentation/${MAJOR_MINOR_VERSION}/reference/html/mapstruct-reference-guide.html static/documentation/${MAJOR_MINOR_VERSION}/reference/html/index.html +git add static/documentation/${MAJOR_MINOR_VERSION} + +git config --global user.email "${GH_BOT_EMAIL}" +git config --global user.name "GitHub Action" +git commit -a -m "Releasing version ${VERSION}" +git push diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..0c6333a8ff --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,45 @@ +name: CodeQL + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: '37 23 * * 6' + +permissions: {} + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + - language: java-kotlin + build-mode: autobuild + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: Initialize CodeQL + uses: github/codeql-action/init@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + - name: Set up Java + if: matrix.language == 'java-kotlin' + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + with: + distribution: 'zulu' + java-version: '21' + cache: 'maven' + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/java-ea.yml b/.github/workflows/java-ea.yml new file mode 100644 index 0000000000..04897b2156 --- /dev/null +++ b/.github/workflows/java-ea.yml @@ -0,0 +1,24 @@ +name: Java EA + +on: [push] + +permissions: + contents: read + +env: + MAVEN_ARGS: -V -B --no-transfer-progress -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 + +jobs: + test_jdk_ea: + name: 'Linux JDK EA' + runs-on: ubuntu-latest + steps: + - name: 'Checkout' + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: 'Set up JDK' + uses: oracle-actions/setup-java@fff43251af9936a0e6a4d5d0946e14f1680e9b6b # v1.5.0 + with: + website: jdk.java.net + release: EA + - name: 'Test' + run: ./mvnw ${MAVEN_ARGS} -Djacoco.skip=true install -DskipDistribution=true diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000000..865820f6ab --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,23 @@ +name: Mac OS CI + +on: push + +permissions: + contents: read + +env: + MAVEN_ARGS: -V -B --no-transfer-progress -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 + +jobs: + mac: + name: 'Mac OS' + runs-on: macos-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: 'Set up JDK 21' + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + with: + distribution: 'zulu' + java-version: 21 + - name: 'Test' + run: ./mvnw ${MAVEN_ARGS} install diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000000..d1ebef4642 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,66 @@ +name: CI + +on: [push, pull_request] + +permissions: + contents: read + +env: + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + MAVEN_ARGS: -V -B --no-transfer-progress -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120 + +jobs: + test_jdk: + strategy: + fail-fast: false + matrix: + java: [21, 25, 26] + name: 'Linux JDK ${{ matrix.java }}' + runs-on: ubuntu-latest + steps: + - name: 'Checkout' + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: 'Set up JDK' + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + with: + distribution: 'zulu' + java-version: ${{ matrix.java }} + - name: 'Test' + run: ./mvnw ${MAVEN_ARGS} -Djacoco.skip=${{ matrix.java != 21 }} install -DskipDistribution=${{ matrix.java != 21 }} + - name: 'Generate coverage report' + if: matrix.java == 21 + run: ./mvnw jacoco:report + - name: 'Upload coverage to Codecov' + if: matrix.java == 21 && github.repository == 'mapstruct/mapstruct' + uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 + with: + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + - name: 'Publish Snapshots' + if: matrix.java == 21 && github.event_name == 'push' && github.ref == 'refs/heads/main' && github.repository == 'mapstruct/mapstruct' + run: ./mvnw -s etc/ci-settings.xml -DskipTests=true -DskipDistribution=true deploy + integration_test_jdk: + strategy: + fail-fast: false + matrix: + java: [ 8, 17 ] + name: 'Linux JDK ${{ matrix.java }}' + runs-on: ubuntu-latest + steps: + - name: 'Checkout' + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - name: 'Set up JDK 21 for building everything' + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + with: + distribution: 'zulu' + java-version: 21 + - name: 'Install Processor' + run: ./mvnw ${MAVEN_ARGS} -DskipTests install -pl processor -am + - name: 'Set up JDK ${{ matrix.java }} for running integration tests' + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + with: + distribution: 'zulu' + java-version: ${{ matrix.java }} + - name: 'Run integration tests' + run: ./mvnw ${MAVEN_ARGS} verify -pl integrationtest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000000..58440dcebd --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,124 @@ +name: Release + +on: + workflow_dispatch: + inputs: + version: + description: 'Release version' + required: true + next: + description: 'Next version' + required: false + +jobs: + release: + # This job has been inspired by the moditect release (https://github.com/moditect/moditect/blob/main/.github/workflows/release.yml) + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + fetch-depth: 0 + + - name: Setup Java + uses: actions/setup-java@1bcf9fb12cf4aa7d266a90ae39939e61372fe520 # v5.4.0 + with: + java-version: 21 + distribution: 'zulu' + cache: maven + + - name: Set release version + id: version + run: | + RELEASE_VERSION=${{ github.event.inputs.version }} + NEXT_VERSION=${{ github.event.inputs.next }} + PLAIN_VERSION=`echo ${RELEASE_VERSION} | awk 'match($0, /^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)/) { print substr($0, RSTART, RLENGTH); }'` + COMPUTED_NEXT_VERSION="${PLAIN_VERSION}-SNAPSHOT" + if [ -z $NEXT_VERSION ] + then + NEXT_VERSION=$COMPUTED_NEXT_VERSION + fi + ./mvnw -ntp -B versions:set versions:commit -DnewVersion=$RELEASE_VERSION -pl :mapstruct-parent -DgenerateBackupPoms=false + git config --global user.email "${{ vars.GH_BOT_EMAIL }}" + git config --global user.name "GitHub Action" + git commit -a -m "Releasing version $RELEASE_VERSION" + git push + echo "RELEASE_VERSION=$RELEASE_VERSION" >> $GITHUB_ENV + echo "NEXT_VERSION=$NEXT_VERSION" >> $GITHUB_ENV + echo "PLAIN_VERSION=$PLAIN_VERSION" >> $GITHUB_ENV + + - name: Stage + run: | + export GPG_TTY=$(tty) + ./mvnw -ntp -B --file pom.xml \ + -Dmaven.site.skip=true -Drelease=true -Ppublication,stage + + - name: Release + env: + JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + JRELEASER_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }} + JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }} + JRELEASER_GPG_SECRET_KEY: ${{ secrets.GPG_PRIVATE_KEY }} + JRELEASER_MAVENCENTRAL_SONATYPE_USERNAME: ${{ secrets.SONATYPE_CENTRAL_USERNAME }} + JRELEASER_MAVENCENTRAL_SONATYPE_TOKEN: ${{ secrets.SONATYPE_CENTRAL_TOKEN }} + JRELEASER_NEXUS2_MAVEN_CENTRAL_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + JRELEASER_NEXUS2_MAVEN_CENTRAL_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + run: | + ./mvnw -ntp -B --file pom.xml -pl :mapstruct-parent -Pjreleaser jreleaser:release + + - name: JReleaser output + if: always() + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: jreleaser-release + path: | + parent/target/jreleaser/trace.log + parent/target/jreleaser/output.properties + + - name: Reset NEXT_RELEASE_CHANGELOG.md + run: | + echo -e "### Features\n\n### Enhancements\n\n### Bugs\n\n### Documentation\n\n### Build\n" > NEXT_RELEASE_CHANGELOG.md + + - name: Set next version + run: | + ./mvnw -ntp -B versions:set versions:commit -DnewVersion=${{ env.NEXT_VERSION }} -pl :mapstruct-parent -DgenerateBackupPoms=false + sed -i -e "s@project.build.outputTimestamp>.*\${git.commit.author.time} @@ -25,7 +12,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml diff --git a/build-config/src/main/resources/build-config/checkstyle.xml b/build-config/src/main/resources/build-config/checkstyle.xml index 1f371acd2b..b15e108c5c 100644 --- a/build-config/src/main/resources/build-config/checkstyle.xml +++ b/build-config/src/main/resources/build-config/checkstyle.xml @@ -15,6 +15,8 @@ --> + + - + + + + + + + + + + @@ -60,10 +71,6 @@ - - - - @@ -113,14 +120,18 @@ + + + + + + + - - - - @@ -138,12 +149,14 @@ - + - + + + @@ -202,9 +215,9 @@ + - diff --git a/build-config/src/main/resources/build-config/import-control.xml b/build-config/src/main/resources/build-config/import-control.xml index 7e04d49ce7..6c8056bd8d 100644 --- a/build-config/src/main/resources/build-config/import-control.xml +++ b/build-config/src/main/resources/build-config/import-control.xml @@ -10,8 +10,8 @@ - - + + diff --git a/copyright.txt b/copyright.txt index eddc353b64..74f18d89b1 100644 --- a/copyright.txt +++ b/copyright.txt @@ -1,42 +1,95 @@ Contributors ============ +Aleksey Ivashin - https://github.com/xumk Alexandr Shalugin - https://github.com/shalugin +Amine Touzani - https://github.com/ttzn Andreas Gudian - https://github.com/agudian +Andrei Arlou - https://github.com/Captain1653 +Andres Jose Sebastian Rincon Gonzalez - https://github.com/stianrincon +Arne Seime - https://github.com/seime +Burak Yildirim - https://github.com/bydrim +Cause Chung - https://github.com/cuzfrog Christian Bandowski - https://github.com/chris922 +Chris DeLashmutt - https://github.com/cdelashmutt-pivotal +Christian Kosmowski - https://github.com/ckosmowski Christian Schuster - https://github.com/chschu Christophe Labouisse - https://github.com/ggtools Ciaran Liedeman - https://github.com/cliedeman +Cindy Wang - https://github.com/birdfriend Cornelius Dirmeier - https://github.com/cornzy +Dennis Melzer - https://github.com/ David Feinblum - https://github.com/dvfeinblum Darren Rambaud - https://github.com/xyzst +Dekel Pilli - https://github.com/dekelpilli Dilip Krishnan - https://github.com/dilipkrish Dmytro Polovinkin - https://github.com/navpil +Ewald Volkert - https://github.com/eforest Eric Martineau - https://github.com/ericmartineau Ewald Volkert - https://github.com/eforest Filip Hrisafov - https://github.com/filiphr +Florian Tavares - https://github.com/neoXfire Gervais Blaise - https://github.com/gervaisb +Gibou Damien - https://github.com/dmngb Gunnar Morling - https://github.com/gunnarmorling +hduelme - https://github.com/hduelme Ivo Smid - https://github.com/bedla +Jason Bodnar - https://github.com/Blackbaud-JasonBodnar +Jeroen van Wilgenburg - https://github.com/jvwilge Jeff Smyth - https://github.com/smythie86 +jmwbRyDWLeNsvtzrihGoY - https://github.com/jmwbRyDWLeNsvtzrihGoY +João Paulo Bassinello - https://github.com/jpbassinello +Jonathan Kraska - https://github.com/jakraska Joshua Spoerri - https://github.com/spoerri +Jude Niroshan - https://github.com/JudeNiroshan +Justyna Kubica-Ledzion - https://github.com/JKLedzion +Kemal Özcan - https://github.com/yekeoe +Ken Wang - https://github.com/ro0sterjam Kevin Grüneberg - https://github.com/kevcodez +Lukas Lazar - https://github.com/LukeLaz +Nikolas Charalambidis - https://github.com/Nikolas-Charalambidis +Maciej Kucharczyk - https://github.com/mk868 Michael Pardo - https://github.com/pardom +Muhammad Usama - https://github.com/the-mgi Mustafa Caylak - https://github.com/luxmeter +Neale Upstone - https://github.com/nealeu Oliver Ehrenmüller - https://github.com/greuelpirat +Oliver Erhart - https://github.com/thunderhook Paul Strugnell - https://github.com/ps-powa Pascal Grün - https://github.com/pascalgn Pavel Makhov - https://github.com/streetturtle Peter Larson - https://github.com/pjlarson +Raimund Klein - https://github.com/Chessray Remko Plantenga - https://github.com/sonata82 Remo Meier - https://github.com/remmeier +Roel Mangelschots - https://github.com/rmschots +Ritesh Chopade - https://github.com/codeswithritesh Richard Lea - https://github.com/chigix +Roman Obolonskyi - https://github.com/Obolrom +Samil Can - https://github.com/SamilCan +Saheb Preet Singh - https://github.com/sahebpreet Samuel Wright - https://github.com/samwright +Sebastian Haberey - https://github.com/sebastianhaberey Sebastian Hasait - https://github.com/shasait Sean Huang - https://github.com/seanjob +seonwoojung - https://github.com/seonwooj0810 Sjaak Derksen - https://github.com/sjaakd Stefan May - https://github.com/osthus-sm +Takch02 - https://github.com/Takch02 +Taras Mychaskiw - https://github.com/twentylemon +Thibault Duperron - https://github.com/Zomzog +Tomáš Poledný - https://github.com/Saljack +Tobias Meggendorfer - https://github.com/incaseoftrouble +Tran Ngoc Nhan - https://github.com/ Tillmann Gaida - https://github.com/Tillerino Timo Eckhardt - https://github.com/timoe Tomek Gubala - https://github.com/vgtworld +Valentin Kulesh - https://github.com/unshare Vincent Alexander Beelte - https://github.com/grandmasterpixel +Winter Andreas - https://github.dev/wandi34 +Xiu Hong Kooi - https://github.com/kooixh +Yang Tang - https://github.com/tangyang9464 +Yevhen Vasyliev - https://github.com/yvasyliev +Zegveld - https://github.com/Zegveld +znight1020 - https://github.com/znight1020 +zral - https://github.com/zyberzebra diff --git a/core-common/pom.xml b/core-common/pom.xml deleted file mode 100644 index b1d066a4bf..0000000000 --- a/core-common/pom.xml +++ /dev/null @@ -1,71 +0,0 @@ - - - - 4.0.0 - - - org.mapstruct - mapstruct-parent - 1.3.0-SNAPSHOT - ../parent/pom.xml - - - mapstruct-common - jar - MapStruct Core Common - - - true - true - - - - - junit - junit - test - - - org.assertj - assertj-core - test - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - check-style - verify - - checkstyle - - - - - - - diff --git a/core-common/src/main/java/org/mapstruct/BeanMapping.java b/core-common/src/main/java/org/mapstruct/BeanMapping.java deleted file mode 100644 index 03a0ee10f2..0000000000 --- a/core-common/src/main/java/org/mapstruct/BeanMapping.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Configures the mapping between two bean types. - *

- * Either {@link #resultType()}, {@link #qualifiedBy()} or {@link #nullValueMappingStrategy()} must be specified. - *

- * - * @author Sjaak Derksen - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface BeanMapping { - - /** - * Specifies the result type of the factory method to be used in case several factory methods qualify. - * - * @return the resultType to select - */ - Class resultType() default void.class; - - /** - * A qualifier can be specified to aid the selection process of a suitable factory method or filtering applicable - * {@code @}{@link BeforeMapping} / {@code @}{@link AfterMapping} methods. This is useful in case multiple factory - * method (hand written of internal) qualify and result in an 'Ambiguous factory methods' error. - *

- * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. - * - * @return the qualifiers - * @see BeanMapping#qualifiedByName() - */ - Class[] qualifiedBy() default { }; - - /** - * Similar to {@link #qualifiedBy()}, but used in combination with {@code @}{@link Named} in case no custom - * qualifier annotation is defined. - * - * @return the qualifiers - * @see Named - */ - String[] qualifiedByName() default { }; - - /** - * The strategy to be applied when {@code null} is passed as source value to this bean mapping. If no - * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or - * {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL} - * by default. - * - * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping. - */ - NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; - - /** - * Default ignore all mappings. All mappings have to be defined manually. No automatic mapping will take place. No - * warning will be issued on missing target properties. - * - * @return The ignore strategy (default false). - * - * @since 1.3 - */ - boolean ignoreByDefault() default false; - - /** - * Unmapped source properties to be ignored. This could be used when {@link ReportingPolicy#WARN} - * or {@link ReportingPolicy#ERROR} is used for {@link Mapper#unmappedSourcePolicy()} or - * {@link MapperConfig#unmappedSourcePolicy()}. Listed properties will be ignored when composing the unmapped - * source properties report. - *

- * NOTE: This does not support ignoring nested source properties - * - * @return The source properties that should be ignored when performing a report - * - * @since 1.3 - */ - String[] ignoreUnmappedSourceProperties() default {}; - - /** - * The information that should be used for the builder mappings. This can be used to define custom build methods - * for the builder strategy that one uses. - * - * If no builder is defined the builder given via {@link MapperConfig#builder()} or {@link Mapper#builder()} - * will be applied. - *

- * NOTE: In case no builder is defined here, in {@link Mapper} or {@link MapperConfig} and there is a single - * build method, then that method would be used. - *

- * If the builder is defined and there is a single method that does not match the name of the finisher than - * a compile error will occurs - * - * @return the builder information for the method level - * - * @since 1.3 - */ - Builder builder() default @Builder; -} diff --git a/core-common/src/main/java/org/mapstruct/Builder.java b/core-common/src/main/java/org/mapstruct/Builder.java deleted file mode 100644 index 5f37028d8e..0000000000 --- a/core-common/src/main/java/org/mapstruct/Builder.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.mapstruct.util.Experimental; - -/** - * Configuration of builders, e.g. the name of the final build method. - * - * @author Filip Hrisafov - * - * @since 1.3 - */ -@Retention(RetentionPolicy.CLASS) -@Target({}) -@Experimental -public @interface Builder { - - /** - * The name of the build method that needs to be invoked on the builder to create the type to be build - * - * @return the method that needs to tbe invoked on the builder - */ - String buildMethod() default "build"; -} diff --git a/core-common/src/main/java/org/mapstruct/CollectionMappingStrategy.java b/core-common/src/main/java/org/mapstruct/CollectionMappingStrategy.java deleted file mode 100644 index 556e8aab01..0000000000 --- a/core-common/src/main/java/org/mapstruct/CollectionMappingStrategy.java +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -/** - * Strategy for propagating the value of collection-typed properties from source to target. - * - * @author Sjaak Derksen - */ -public enum CollectionMappingStrategy { - - /** - * The setter of the target property will be used to propagate the value: - * {@code orderDto.setOrderLines(order.getOrderLines)}. - *

- * If no setter is available but a getter method, this will be used, under the assumption it has been initialized: - * {@code orderDto.getOrderLines().addAll(order.getOrderLines)}. This will also be the case when using - * {@link MappingTarget} (updating existing instances). - */ - ACCESSOR_ONLY, - - /** - * If present, the setter of the target property will be used to propagate the value: - * {@code orderDto.setOrderLines(order.getOrderLines)}. - *

- * If no setter but and adder method is present, that adder will be invoked for each element of the source - * collection: {@code order.addOrderLine(orderLine() )}. - *

- * If neither a setter nor an adder method but a getter for the target property is present, that getter will be - * used, assuming it returns an initialized collection: If no setter is available, MapStruct will first look for an - * adder method before resorting to a getter. - */ - SETTER_PREFERRED, - - /** - * Identical to {@link #SETTER_PREFERRED}, only that adder methods will be preferred over setter methods, if both - * are present for a given collection-typed property. - */ - ADDER_PREFERRED, - - /** - * Identical to {@link #SETTER_PREFERRED}, however the target collection will not be cleared and accessed via - * addAll in case of updating existing bean instances, see: {@link MappingTarget}. - * - * Instead the target accessor (e.g. set) will be used on the target bean to set the collection. - */ - TARGET_IMMUTABLE; -} diff --git a/core-common/src/main/java/org/mapstruct/InheritConfiguration.java b/core-common/src/main/java/org/mapstruct/InheritConfiguration.java deleted file mode 100644 index cdbae1d57a..0000000000 --- a/core-common/src/main/java/org/mapstruct/InheritConfiguration.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Advises the code generator to apply the configuration (as given via {@link Mapping}, {@link IterableMapping} etc.) - * from another mapping method (declared on the same mapper type) or prototype method (declared on a mapper config class - * referenced via {@link Mapper#config()}) to the annotated method as well. - *

- * If no method can be identified unambiguously as configuration source (i.e. several candidate methods with matching - * source and target type exist), the name of the method to inherit from must be specified via {@link #name()}. - *

- * A typical use case is annotating an update method so it inherits all mappings from a corresponding "standard" mapping - * method: - * - *

- * 
- * @Mappings({
- *     @Mapping(target="make", source="brand"),
- *     @Mapping(target="seatCount", source="numberOfSeats")
- * })
- * CarDto carToCarDto(Car car);
- *
- * @InheritConfiguration
- * void updateCarDto(Car car, @MappingTarget CarDto carDto);
- * 
- * 
- * - * @author Sjaak Derksen - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface InheritConfiguration { - - /** - * The name of the mapping method to inherit the mappings from. Needs only to be specified in case more than one - * method with matching source and target type exists. - * - * @return The name of the mapping method to inherit the mappings from. - */ - String name() default ""; -} diff --git a/core-common/src/main/java/org/mapstruct/InheritInverseConfiguration.java b/core-common/src/main/java/org/mapstruct/InheritInverseConfiguration.java deleted file mode 100644 index 5ec1c21a74..0000000000 --- a/core-common/src/main/java/org/mapstruct/InheritInverseConfiguration.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Advises the code generator to apply all the {@link Mapping}s from an inverse mapping method to the annotated method - * as well. An inverse mapping method is a method which has the annotated method's source type as target type (return - * type or indicated through a parameter annotated with {@link MappingTarget}) and the annotated method's target type as - * source type. - *

- * Any mappings given on the annotated method itself are added to those mappings inherited from the inverse method. In - * case of a conflict local mappings take precedence over inherited mappings. - *

- * If more than one matching inverse method exists, the name of the method to inherit the configuration from must be - * specified via {@link #name()} - * - * @author Sjaak Derksen - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface InheritInverseConfiguration { - - /** - * The name of the inverse mapping method to inherit the mappings from. Needs only to be specified in case more than - * one inverse method with matching source and target type exists. - * - * @return The name of the inverse mapping method to inherit the mappings from. - */ - String name() default ""; -} diff --git a/core-common/src/main/java/org/mapstruct/InjectionStrategy.java b/core-common/src/main/java/org/mapstruct/InjectionStrategy.java deleted file mode 100644 index 75728d139f..0000000000 --- a/core-common/src/main/java/org/mapstruct/InjectionStrategy.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -/** - * Strategy for handling injection. This is only used on annotated based component models such as CDI, Spring and - * JSR330. - * - * @author Kevin Grüneberg - */ -public enum InjectionStrategy { - - /** Annotations are written on the field **/ - FIELD, - - /** Annotations are written on the constructor **/ - CONSTRUCTOR -} diff --git a/core-common/src/main/java/org/mapstruct/IterableMapping.java b/core-common/src/main/java/org/mapstruct/IterableMapping.java deleted file mode 100644 index efc26ce3a2..0000000000 --- a/core-common/src/main/java/org/mapstruct/IterableMapping.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.text.SimpleDateFormat; -import java.text.DecimalFormat; -import java.util.Date; - -/** - * Configures the mapping between two iterable like types, e.g. {@code List} and {@code List}. - * - * - *

Note: either @IterableMapping#dateFormat, @IterableMapping#resultType or @IterableMapping#qualifiedBy - * must be specified

- * - * Supported mappings are: - * - * - * @author Gunnar Morling - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface IterableMapping { - - /** - * A format string as processable by {@link SimpleDateFormat} if the annotated method maps from an iterable of - * {@code String} to an iterable {@link Date} or vice-versa. Will be ignored for all other element types. - * - * @return A date format string as processable by {@link SimpleDateFormat}. - */ - String dateFormat() default ""; - - /** - * A format string as processable by {@link DecimalFormat} if the annotated method maps from a - * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other element types. - * - * @return A decimal format string as processable by {@link DecimalFormat}. - */ - String numberFormat() default ""; - - /** - * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple - * mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' error. - * - * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. - * - * @return the qualifiers - */ - Class[] qualifiedBy() default { }; - - /** - * String-based form of qualifiers; When looking for a suitable mapping method to map this iterable mapping method's - * element type, MapStruct will only consider those methods carrying directly or indirectly (i.e. on the - * class-level) a {@link Named} annotation for each of the specified qualifier names. - *

- * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and - * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large - * number of qualifiers as no custom annotation types are needed. - * - * @return One or more qualifier name(s) - * @see #qualifiedBy() - * @see Named - */ - String[] qualifiedByName() default { }; - - /** - * Specifies the type of the element to be used in the result of the mapping method in case multiple mapping - * methods qualify. - * - * @return the elementTargetType to select - */ - Class elementTargetType() default void.class; - - - /** - * The strategy to be applied when {@code null} is passed as source value to this iterable mapping. If no - * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or - * {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL} - * by default. - * - * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping. - */ - NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; -} diff --git a/core-common/src/main/java/org/mapstruct/MapMapping.java b/core-common/src/main/java/org/mapstruct/MapMapping.java deleted file mode 100644 index d3c68ec535..0000000000 --- a/core-common/src/main/java/org/mapstruct/MapMapping.java +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.text.SimpleDateFormat; -import java.text.DecimalFormat; -import java.util.Date; - -/** - * Configures the mapping between two map types, e.g. {@code Map} and {@code Map}. - * - *

Note: at least one element needs to be specified

- * - * @author Gunnar Morling - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface MapMapping { - - /** - * A format string as processable by {@link SimpleDateFormat} if the annotated method maps from a map with key type - * {@code String} to an map with key type {@link Date} or vice-versa. Will be ignored for all other key types. - * - * @return A date format string as processable by {@link SimpleDateFormat}. - */ - String keyDateFormat() default ""; - - /** - * A format string as processable by {@link SimpleDateFormat} if the annotated method maps from a map with value - * type {@code String} to an map with value type {@link Date} or vice-versa. Will be ignored for all other value - * types. - * - * @return A date format string as processable by {@link SimpleDateFormat}. - */ - String valueDateFormat() default ""; - - /** - * A format string as processable by {@link DecimalFormat} if the annotated method maps from a - * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other key types. - * - * @return A decimal format string as processable by {@link DecimalFormat}. - */ - String keyNumberFormat() default ""; - - /** - * A format string as processable by {@link DecimalFormat} if the annotated method maps from a - * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other value types. - * - * @return A decimal format string as processable by {@link DecimalFormat}. - */ - String valueNumberFormat() default ""; - - /** - * A key value qualifier can be specified to aid the selection process of a suitable mapper. This is useful in - * case multiple mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' - * error. - * - * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. - * - * @return the qualifiers - */ - Class[] keyQualifiedBy() default { }; - - /** - * String-based form of qualifiers; When looking for a suitable mapping method to map this map mapping method's key - * type, MapStruct will only consider those methods carrying directly or indirectly (i.e. on the class-level) a - * {@link Named} annotation for each of the specified qualifier names. - *

- * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and - * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large - * number of qualifiers as no custom annotation types are needed. - * - * @return One or more qualifier name(s) - * @see #keyQualifiedBy() - * @see Named - */ - String[] keyQualifiedByName() default { }; - - - /** - * A value qualifier can be specified to aid the selection process of a suitable mapper for the values in the map. - * This is useful in case multiple mappers (hand written of internal) qualify and result in an 'Ambiguous mapping - * methods found' error. - *

- * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. - * - * @return the qualifiers - */ - Class[] valueQualifiedBy() default { }; - - /** - * String-based form of qualifiers; When looking for a suitable mapping method to map this map mapping method's - * value type, MapStruct will only consider those methods carrying directly or indirectly (i.e. on the class-level) - * a {@link Named} annotation for each of the specified qualifier names. - *

- * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and - * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large - * number of qualifiers as no custom annotation types are needed. - * - * @return One or more qualifier name(s) - * @see #valueQualifiedBy() - * @see Named - */ - String[] valueQualifiedByName() default { }; - - /** - * Specifies the type of the key to be used in the result of the mapping method in case multiple mapping - * methods qualify. - * - * - * @return the resultType to select - */ - Class keyTargetType() default void.class; - - /** - * Specifies the type of the value to be used in the result of the mapping method in case multiple mapping - * methods qualify. - * - * - * @return the resultType to select - */ - Class valueTargetType() default void.class; - - - /** - * The strategy to be applied when {@code null} is passed as source value to this map mapping. If no - * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or - * {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL} - * by default. - * - * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping. - */ - NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; -} diff --git a/core-common/src/main/java/org/mapstruct/Mapper.java b/core-common/src/main/java/org/mapstruct/Mapper.java deleted file mode 100644 index 011c83a1f6..0000000000 --- a/core-common/src/main/java/org/mapstruct/Mapper.java +++ /dev/null @@ -1,221 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.mapstruct.factory.Mappers; - -import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; - -/** - * Marks an interface or abstract class as a mapper and activates the generation of a implementation of that type via - * MapStruct. - * - * @author Gunnar Morling - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.CLASS) -public @interface Mapper { - - /** - * Other mapper types used by this mapper. May be hand-written classes or other mappers generated by MapStruct. No - * cycle between generated mapper classes must be created. - * - * @return The mapper types used by this mapper. - */ - Class[] uses() default { }; - - /** - * Additional types for which an import statement is to be added to the generated mapper implementation class. - * This allows to refer to those types from within mapping expressions given via {@link Mapping#expression()}, - * {@link Mapping#defaultExpression()} or using - * their simple name rather than their fully-qualified name. - * - * @return classes to add in the imports of the generated implementation. - */ - Class[] imports() default { }; - - /** - * How unmapped properties of the source type of a mapping should be - * reported. The method overrides an unmappedSourcePolicy set in a central - * configuration set by {@link #config() } - * - * @return The reporting policy for unmapped source properties. - * - * @since 1.3 - */ - ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE; - - /** - * How unmapped properties of the target type of a mapping should be - * reported. The method overrides an unmappedTargetPolicy set in a central - * configuration set by {@link #config() } - * - * @return The reporting policy for unmapped target properties. - */ - ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN; - - /** - * Specifies the component model to which the generated mapper should - * adhere. Supported values are - *

    - *
  • {@code default}: the mapper uses no component model, instances are - * typically retrieved via {@link Mappers#getMapper(Class)}
  • - *
  • - * {@code cdi}: the generated mapper is an application-scoped CDI bean and - * can be retrieved via {@code @Inject}
  • - *
  • - * {@code spring}: the generated mapper is a Spring bean and - * can be retrieved via {@code @Autowired}
  • - *
  • - * {@code jsr330}: the generated mapper is annotated with {@code @javax.inject.Named} and - * {@code @Singleton}, and can be retrieved via {@code @Inject}
  • - *
- * The method overrides an unmappedTargetPolicy set in a central configuration set - * by {@link #config() } - * - * @return The component model for the generated mapper. - */ - String componentModel() default "default"; - - /** - * Specifies the name of the implementation class. The {@code } will be replaced by the - * interface/abstract class name. - *

- * Defaults to postfixing the name with {@code Impl}: {@code Impl} - * - * @return The implementation name. - * @see #implementationPackage() - */ - String implementationName() default "Impl"; - - /** - * Specifies the target package for the generated implementation. The {@code } will be replaced by the - * interface's or abstract class' package. - *

- * Defaults to using the same package as the mapper interface/abstract class - * - * @return the implementation package. - * @see #implementationName() - */ - String implementationPackage() default ""; - - /** - * A class annotated with {@link MapperConfig} which should be used as configuration template. Any settings given - * via {@link Mapper} will take precedence over the settings from the referenced configuration source. The list of - * referenced mappers will contain all mappers given via {@link Mapper#uses()} and {@link MapperConfig#uses()}. - * - * @return A class which should be used as configuration template. - */ - Class config() default void.class; - - /** - * The strategy to be applied when propagating the value of collection-typed properties. By default, only JavaBeans - * accessor methods (setters or getters) will be used, but it is also possible to invoke a corresponding adder - * method for each element of the source collection (e.g. {@code orderDto.addOrderLine()}). - *

- * Any setting given for this attribute will take precedence over {@link MapperConfig#collectionMappingStrategy()}, - * if present. - * - * @return The strategy applied when propagating the value of collection-typed properties. - */ - CollectionMappingStrategy collectionMappingStrategy() default CollectionMappingStrategy.ACCESSOR_ONLY; - - /** - * The strategy to be applied when {@code null} is passed as source value to the methods of this mapper. If no - * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} will be applied, - * using {@link NullValueMappingStrategy#RETURN_NULL} by default. - * - * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapper. - */ - NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; - - /** - * The strategy to use for applying method-level configuration annotations of prototype methods in the interface - * specified with {@link #config()}. Annotations that can be inherited are for example {@link Mapping}, - * {@link IterableMapping}, {@link MapMapping}, or {@link BeanMapping}. - *

- * If no strategy is configured, the strategy given via {@link MapperConfig#mappingInheritanceStrategy()} will be - * applied, using {@link MappingInheritanceStrategy#EXPLICIT} as default. - * - * @return The strategy to use for applying {@code @Mapping} configurations of prototype methods in the interface - * specified with {@link #config()}. - */ - MappingInheritanceStrategy mappingInheritanceStrategy() default MappingInheritanceStrategy.EXPLICIT; - - /** - * Determines when to include a null check on the source property value of a bean mapping. - * - * Can be overridden by the one on {@link MapperConfig} or {@link Mapping}. - * - * @return strategy how to do null checking - */ - NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; - - /** - * Determines whether to use field or constructor injection. This is only used on annotated based component models - * such as CDI, Spring and JSR 330. - * - * If no strategy is configured, {@link InjectionStrategy#FIELD} will be used as default. - * - * @return strategy how to inject - */ - InjectionStrategy injectionStrategy() default InjectionStrategy.FIELD; - - /** - * If MapStruct could not find another mapping method or apply an automatic conversion it will try to generate a - * sub-mapping method between the two beans. If this property is set to {@code true} MapStruct will not try to - * automatically generate sub-mapping methods. - *

- * Can be configured by the {@link MapperConfig#disableSubMappingMethodsGeneration()} as well. - *

- * Note: If you need to use {@code disableSubMappingMethodsGeneration} please contact the MapStruct team at - * mapstruct.org or - * github.com/mapstruct/mapstruct to share what problem you - * are facing with the automatic sub-mapping generation. - * - * @return whether the automatic generation of sub-mapping methods is disabled - * - * @since 1.2 - */ - boolean disableSubMappingMethodsGeneration() default false; - - /** - * The information that should be used for the builder mappings. This can be used to define custom build methods - * for the builder strategy that one uses. - * - * If no builder is defined the builder given via {@link MapperConfig#builder()} will be applied. - * - *

- * NOTE: In case no builder is defined here, in {@link BeanMapping} or {@link MapperConfig} and there is a single - * build method, then that method would be used. - *

- * If the builder is defined and there is a single method that does not match the name of the build method then - * a compile error will occur - * - * @return the builder information - * - * @since 1.3 - */ - Builder builder() default @Builder; -} diff --git a/core-common/src/main/java/org/mapstruct/MapperConfig.java b/core-common/src/main/java/org/mapstruct/MapperConfig.java deleted file mode 100644 index 857320b3aa..0000000000 --- a/core-common/src/main/java/org/mapstruct/MapperConfig.java +++ /dev/null @@ -1,209 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.mapstruct.factory.Mappers; - -import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; - -/** - * Marks a class or interface as configuration source for generated mappers. This allows to share common configurations - * between several mapper classes. - *

- * Generally, any settings given via {@link Mapper} take precedence over the settings given via the referenced - * {@code MapperConfig}. The lists of referenced mappers given via {@link Mapper#uses()} and - * {@link MapperConfig#uses()} will be merged. - *

- * Additionally, mapper configuration classes may declare one more prototype mapping methods. These methods are - * not meant to be invoked themselves (no implementation will generated for mapper config classes), but serve as - * configuration template for mapping methods declared by actual mapper classes. Depending on the configured - * {@link #mappingInheritanceStrategy()}, the configuration can be inherited either explicitly using - * {@link InheritConfiguration} or {@link InheritInverseConfiguration}, or automatically in case all source and target - * types are assignable. - *

- * - * @author Sjaak Derksen - * @see Mapper#config() - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.CLASS) -public @interface MapperConfig { - - /** - * The mapper types used by this mapper. - * - * @return The mapper types used by this mapper. - */ - Class[] uses() default { }; - - /** - * How unmapped properties of the source type of a mapping should be - * reported. - * - * @return The reporting policy for unmapped source properties. - * - * @since 1.3 - */ - ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE; - - /** - * How unmapped properties of the target type of a mapping should be - * reported. - * - * @return The reporting policy for unmapped target properties. - */ - ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN; - - /** - * Specifies the component model to which the generated mapper should - * adhere. Supported values are - *
    - *
  • {@code default}: the mapper uses no component model, instances are - * typically retrieved via {@link Mappers#getMapper(Class)}
  • - *
  • - * {@code cdi}: the generated mapper is an application-scoped CDI bean and - * can be retrieved via {@code @Inject}
  • - *
  • - * {@code spring}: the generated mapper is a Spring bean and - * can be retrieved via {@code @Autowired}
  • - *
  • - * {@code jsr330}: the generated mapper is annotated with {@code @javax.inject.Named} and - * {@code @Singleton}, and can be retrieved via {@code @Inject}
  • - *
- * - * @return The component model for the generated mapper. - */ - String componentModel() default "default"; - - /** - * Specifies the name of the implementation class. The {@code } will be replaced by the - * interface/abstract class name. - *

- * Defaults to postfixing the name with {@code Impl}: {@code Impl} - * - * @return The implementation name. - * @see #implementationPackage() - */ - String implementationName() default "Impl"; - - /** - * Specifies the target package for the generated implementation. The {@code } will be replaced by the - * interface's or abstract class' package. - *

- * Defaults to using the same package as the mapper interface/abstract class - * - * @return the implementation package. - * @see #implementationName() - */ - String implementationPackage() default ""; - - /** - * The strategy to be applied when propagating the value of collection-typed properties. By default, only JavaBeans - * accessor methods (setters or getters) will be used, but it is also possible to invoke a corresponding adder - * method for each element of the source collection (e.g. {@code orderDto.addOrderLine()}). - * - * @return The strategy applied when propagating the value of collection-typed properties. - */ - CollectionMappingStrategy collectionMappingStrategy() default CollectionMappingStrategy.ACCESSOR_ONLY; - - /** - * The strategy to be applied when {@code null} is passed as source value to mapping methods. If no strategy is - * configured, {@link NullValueMappingStrategy#RETURN_NULL} will be used by default. - * - * @return The strategy to be applied when {@code null} is passed as source value to mapping methods. - */ - NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; - - /** - * The strategy to use for applying method-level configuration annotations of prototype methods in the interface - * annotated with this annotation. Annotations that can be inherited are for example {@link Mapping}, - * {@link IterableMapping}, {@link MapMapping}, or {@link BeanMapping}. - *

- * If no strategy is configured, {@link MappingInheritanceStrategy#EXPLICIT} will be used as default. - * - * @return The strategy to use for applying {@code @Mapping} configurations of prototype methods in the interface - * annotated with this annotation. - */ - MappingInheritanceStrategy mappingInheritanceStrategy() - default MappingInheritanceStrategy.EXPLICIT; - - /** - * Determines when to include a null check on the source property value of a bean mapping. - * - * Can be overridden by the one on {@link Mapper} or {@link Mapping}. - * - * @return strategy how to do null checking - */ - NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; - - /** - * Determines whether to use field or constructor injection. This is only used on annotated based component models - * such as CDI, Spring and JSR 330. - * - * Can be overridden by the one on {@link Mapper}. - * - * If no strategy is configured, {@link InjectionStrategy#FIELD} will be used as default. - * - * @return strategy how to inject - */ - InjectionStrategy injectionStrategy() default InjectionStrategy.FIELD; - - /** - * If MapStruct could not find another mapping method or apply an automatic conversion it will try to generate a - * sub-mapping method between the two beans. If this property is set to {@code true} MapStruct will not try to - * automatically generate sub-mapping methods. - *

- * Can be overridden by {@link Mapper#disableSubMappingMethodsGeneration()} - *

- * Note: If you need to use {@code disableSubMappingMethodsGeneration} please contact the MapStruct team at - * mapstruct.org or - * github.com/mapstruct/mapstruct to share what problem you - * are facing with the automatic sub-mapping generation. - * - * @return whether the automatic generation of sub-mapping methods is disabled - * - * @since 1.2 - */ - boolean disableSubMappingMethodsGeneration() default false; - - /** - * The information that should be used for the builder mappings. This can be used to define custom build methods - * for the builder strategy that one uses. - * - *

- * Can be overridden by {@link MapperConfig#builder()}. - * - *

- * NOTE: In case no builder is defined here, in {@link BeanMapping} or {@link Mapper} and there is a single - * build method, then that method would be used. - *

- * If the builder is defined and there is a single method that does not match the name of the build method then - * a compile error will occur - * - * @return the builder information - * - * @since 1.3 - */ - Builder builder() default @Builder; -} diff --git a/core-common/src/main/java/org/mapstruct/MappingConstants.java b/core-common/src/main/java/org/mapstruct/MappingConstants.java deleted file mode 100644 index c4f7dbbf20..0000000000 --- a/core-common/src/main/java/org/mapstruct/MappingConstants.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -/** - * Contains all constants defined in the mapping process. - * - * @author Sjaak Derksen - */ -public final class MappingConstants { - - private MappingConstants() { - } - - /** - * Represents a {@code null} source or target. - */ - public static final String NULL = ""; - - /** - * Represents any source that is not already mapped by either a defined mapping or by means of name based mapping. - */ - public static final String ANY_REMAINING = ""; - - /** - * Represents any source that is not already mapped by a defined mapping. - */ - public static final String ANY_UNMAPPED = ""; - -} diff --git a/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java b/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java deleted file mode 100644 index 03f5ee0e77..0000000000 --- a/core-common/src/main/java/org/mapstruct/MappingInheritanceStrategy.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -/** - * Strategy for inheriting configurations given for methods of prototype mapping methods (declared on mapper config - * classes) to actual mapping methods declared on mappers referring to such config class via {@link Mapper#config()}. - * - * @author Andreas Gudian - */ -public enum MappingInheritanceStrategy { - /** - * Apply the method-level configuration annotations only if the prototype method is explicitly referenced using - * {@link InheritConfiguration}. - */ - EXPLICIT, - - /** - * Inherit the method-level forward configuration annotations automatically if source and target types of the - * prototype method are assignable from the types of a given mapping method. - */ - AUTO_INHERIT_FROM_CONFIG, - - /** - * Inherit the method-level reverse configuration annotations automatically if source and target types of the - * prototype method are assignable from the target and source types of a given mapping method. - */ - AUTO_INHERIT_REVERSE_FROM_CONFIG, - - /** - * Inherit the method-level forward and reverse configuration annotations automatically if source and target types - * of the prototype method are assignable from the types of a given mapping method. - */ - AUTO_INHERIT_ALL_FROM_CONFIG; -} diff --git a/core-common/src/main/java/org/mapstruct/MappingTarget.java b/core-common/src/main/java/org/mapstruct/MappingTarget.java deleted file mode 100644 index f99c79885d..0000000000 --- a/core-common/src/main/java/org/mapstruct/MappingTarget.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Declares a parameter of a mapping method to be the target of the mapping. - *

- * Not more than one parameter can be declared as {@code MappingTarget}. - *

- * NOTE: The parameter passed as a mapping target must not be {@code null}. - * - * @author Andreas Gudian - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.CLASS) -public @interface MappingTarget { -} diff --git a/core-common/src/main/java/org/mapstruct/Named.java b/core-common/src/main/java/org/mapstruct/Named.java deleted file mode 100644 index 3a8a27a681..0000000000 --- a/core-common/src/main/java/org/mapstruct/Named.java +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Marks mapping methods with the given qualifier name. Can be used to qualify a single method or all methods of a given - * type by specifying this annotation on the type level. - *

- * Will be used to to select the correct mapping methods when mapping a bean property type, element of an iterable type - * or the key/value of a map type. - *

- * Example (both methods of {@code Titles} are capable to convert a string, but the ambiguity is resolved by applying - * the qualifiers in {@code @Mapping}: - * - *

- * 
- * @Named("TitleTranslator")
- * public class Titles {
- *
- *   @Named("EnglishToGerman")
- *   public String translateTitleEG(String title) {
- *       // some mapping logic
- *   }
- *
- *   @Named("GermanToEnglish")
- *   public String translateTitleGE(String title) {
- *       // some mapping logic
- *   }
- * }
- *
- * @Mapper( uses = Titles.class )
- * public interface MovieMapper {
- *
- *    @Mapping( target = "title", qualifiedByName = { "TitleTranslator", "EnglishToGerman" } )
- *    GermanRelease toGerman( OriginalRelease movies );
- *
- * }
- * 
- * 
- * - * The following implementation of {@code MovieMapper} will be generated: - * - *
- * 
- *
- * public class MovieMapperImpl implements MovieMapper {
- *     private final Titles titles = new Titles();
- *
- *     @Override
- *     public GermanRelease toGerman(OriginalRelease movies) {
- *         if ( movies == null ) {
- *             return null;
- *         }
- *
- *         GermanRelease germanRelease = new GermanRelease();
- *
- *         germanRelease.setTitle( titles.translateTitleEG( movies.getTitle() ) );
- *
- *         return germanRelease;
- *     }
- * }
- * 
- * 
- * - * @author Sjaak Derksen - * @see org.mapstruct.Mapping#qualifiedByName() - * @see IterableMapping#qualifiedByName() - * @see MapMapping#keyQualifiedByName() - * @see MapMapping#valueQualifiedByName() - */ -@Target( { ElementType.TYPE, ElementType.METHOD } ) -@Retention( RetentionPolicy.CLASS ) -@Qualifier -public @interface Named { - - /** - * A name qualifying the annotated element - * - * @return the name. - */ - String value(); -} diff --git a/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java b/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java deleted file mode 100644 index c6c0dbfd5d..0000000000 --- a/core-common/src/main/java/org/mapstruct/NullValueCheckStrategy.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -/** - * Strategy for dealing with null source values. - * - * Note: This strategy is not in effect when the a specific source presence check method is defined - * in the service provider interface (SPI). - * - * @author Sean Huang - */ -public enum NullValueCheckStrategy { - - /** - * This option includes a null check. When: - *
- *
- *
    - *
  1. a source value is directly assigned to a target
  2. - *
  3. a source value assigned to a target by calling a type conversion on the target first
  4. - *
- *
- * NOTE: mapping methods (generated or hand written) are excluded from this null check. They are intended to - * handle a null source value as 'valid' input. - * - */ - ON_IMPLICIT_CONVERSION, - - /** - * This option always includes a null check. - */ - ALWAYS, - -} diff --git a/core-common/src/main/java/org/mapstruct/NullValueMappingStrategy.java b/core-common/src/main/java/org/mapstruct/NullValueMappingStrategy.java deleted file mode 100644 index 4dd77dbb3a..0000000000 --- a/core-common/src/main/java/org/mapstruct/NullValueMappingStrategy.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -/** - * Strategy for dealing with {@code null} values passed to mapping methods. - * - * @author Sjaak Derksen - */ -public enum NullValueMappingStrategy { - - /** - * If {@code null} is passed to a mapping method, {@code null} will be returned. That's the default behavior if no - * alternative strategy is configured globally, for given mapper or method. - */ - RETURN_NULL, - - /** - * If {@code null} is passed to a mapping method, a default value will be returned. The value depends on the kind of - * the annotated method: - *
    - *
  • For bean mapping methods the target type will be instantiated and returned. Any properties of the target type - * which are mapped via {@link Mapping#expression()} or {@link Mapping#constant()} will be populated based on the - * given expression or constant. Note that expressions must be prepared to deal with {@code null} values in this - * case.
  • - *
  • For iterable mapping methods an empty collection will be returned.
  • - *
  • For map mapping methods an empty map will be returned.
  • - *
- */ - RETURN_DEFAULT; -} diff --git a/core-common/src/main/java/org/mapstruct/ObjectFactory.java b/core-common/src/main/java/org/mapstruct/ObjectFactory.java deleted file mode 100644 index 60c0acff02..0000000000 --- a/core-common/src/main/java/org/mapstruct/ObjectFactory.java +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * This annotation marks a method as a factory method to create beans. - *

- * By default beans are created during the mapping process with the default constructor. If a factory method with a - * return type that is assignable to the required object type is present, then the factory method is used instead. - *

- * Factory methods can be defined without parameters, with an {@code @}{@link TargetType} parameter, a - * {@code @}{@link Context} parameter, or with the mapping source parameter. If any of those parameters are defined, - * then the mapping method that is supposed to use the factory method needs to be declared with an assignable result - * type, assignable context parameter, and/or assignable source types. - *

- * Note: the usage of this annotation is optional when used in the {@link Mapper#uses()} - * if no source parameters are part of the signature, i.e. it is declared without parameters or only with - * {@code @}{@link TargetType} and/or {@code @}{@link Context}. It is however mandatory when used inside - * an {@code @}{@link Context} annotated class. - *

- * Example: Using a factory method for entities to check whether the entity already exists in the - * EntityManager and then returns the managed instance: - * - *

- * 
- * @ApplicationScoped // CDI component model
- * public class ReferenceMapper {
- *
- *     @PersistenceContext
- *     private EntityManager em;
- *
- *     @ObjectFactory
- *     public <T extends AbstractEntity> T resolve(AbstractDto sourceDto, @TargetType Class<T> type) {
- *         T entity = em.find( type, sourceDto.getId() );
- *         return entity != null ? entity : type.newInstance();
- *     }
- * }
- * 
- * 
- *

- * If there are two factory methods, both serving the same type, one with no parameters and one taking sources as input, - * then the one with the source parameters is favored. If there are multiple such factories, an ambiguity error is - * shown. - * - * @author Remo Meier - * @since 1.2 - */ -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) -public @interface ObjectFactory { - -} diff --git a/core-common/src/main/java/org/mapstruct/Qualifier.java b/core-common/src/main/java/org/mapstruct/Qualifier.java deleted file mode 100644 index 0581da2da4..0000000000 --- a/core-common/src/main/java/org/mapstruct/Qualifier.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Declares an annotation type to be a qualifier. Qualifier annotations allow unambiguously identify a suitable mapping - * method in case several methods qualify to map a bean property, iterable element etc. - *

- * For more info see: - *

    - *
  • {@link Mapping#qualifiedBy() }
  • - *
  • {@link BeanMapping#qualifiedBy() }
  • - *
  • {@link IterableMapping#qualifiedBy() }
  • - *
  • {@link MapMapping#keyQualifiedBy() }
  • - *
  • {@link MapMapping#valueQualifiedBy() }
  • - *
- * Example: - * - *
- * @Qualifier
- * @Target(ElementType.METHOD)
- * @Retention(RetentionPolicy.CLASS)
- * public @interface EnglishToGerman {
- * }
- * 
- * - * NOTE: Qualifiers should have {@link RetentionPolicy#CLASS}. - * - * @author Sjaak Derksen - * @see Named - */ -@Target(ElementType.ANNOTATION_TYPE) -@Retention(RetentionPolicy.CLASS) -public @interface Qualifier { -} diff --git a/core-common/src/main/java/org/mapstruct/ReportingPolicy.java b/core-common/src/main/java/org/mapstruct/ReportingPolicy.java deleted file mode 100644 index 35c77d4bc7..0000000000 --- a/core-common/src/main/java/org/mapstruct/ReportingPolicy.java +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import javax.tools.Diagnostic.Kind; - -/** - * Policy for reporting issues occurring during the generation of a mapper - * implementation. - * - * @author Gunnar Morling - */ -public enum ReportingPolicy { - - /** - * No report will be created for the given issue. - */ - IGNORE, - - /** - * A report with {@link Kind#WARNING} will be created for the given issue. - */ - WARN, - - /** - * A report with {@link Kind#ERROR} will be created for the given issue, - * causing the compilation to fail. - */ - ERROR; -} diff --git a/core-common/src/main/java/org/mapstruct/TargetType.java b/core-common/src/main/java/org/mapstruct/TargetType.java deleted file mode 100644 index dec252c01b..0000000000 --- a/core-common/src/main/java/org/mapstruct/TargetType.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Declares a parameter of a custom mapping method to be populated with the target type of the mapping. - *

- * Not more than one parameter can be declared as {@code TargetType} and that parameter needs to be of type - * {@link Class} (may be parameterized), or a super-type of it. - * - * @author Andreas Gudian - */ -@Target(ElementType.PARAMETER) -@Retention(RetentionPolicy.CLASS) -public @interface TargetType { -} diff --git a/core-common/src/main/java/org/mapstruct/factory/Mappers.java b/core-common/src/main/java/org/mapstruct/factory/Mappers.java deleted file mode 100644 index 44ab7ae4fb..0000000000 --- a/core-common/src/main/java/org/mapstruct/factory/Mappers.java +++ /dev/null @@ -1,132 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.factory; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; -import java.util.ServiceLoader; - -import org.mapstruct.Mapper; - -/** - * Factory for obtaining mapper instances if no explicit component model such as CDI is configured via - * {@link Mapper#componentModel()}. - *

- * Mapper implementation types are expected to have the same fully qualified name as their interface type, with the - * suffix {@code Impl} appended. When using this factory, mapper types - and any mappers they use - are instantiated by - * invoking their public no-args constructor. - *

- * By convention, a single instance of each mapper is retrieved from the factory and exposed on the mapper interface - * type by declaring a member named {@code INSTANCE} like this: - * - *

- * @Mapper
- * public interface CustomerMapper {
- *
- *     CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class );
- *
- *     // mapping methods...
- * }
- * 
- * - * @author Gunnar Morling - */ -public class Mappers { - - private static final String IMPLEMENTATION_SUFFIX = "Impl"; - - private Mappers() { - } - - /** - * Returns an instance of the given mapper type. - * - * @param clazz The type of the mapper to return. - * @param The type of the mapper to create. - * - * @return An instance of the given mapper type. - */ - public static T getMapper(Class clazz) { - try { - List classLoaders = new ArrayList( 3 ); - classLoaders.add( clazz.getClassLoader() ); - - if ( Thread.currentThread().getContextClassLoader() != null ) { - classLoaders.add( Thread.currentThread().getContextClassLoader() ); - } - - classLoaders.add( Mappers.class.getClassLoader() ); - - return getMapper( clazz, classLoaders ); - } - catch ( ClassNotFoundException e ) { - throw new RuntimeException( e ); - } - catch ( NoSuchMethodException e) { - throw new RuntimeException( e ); - } - } - - private static T getMapper(Class mapperType, Iterable classLoaders) - throws ClassNotFoundException, NoSuchMethodException { - - for ( ClassLoader classLoader : classLoaders ) { - T mapper = doGetMapper( mapperType, classLoader ); - if ( mapper != null ) { - return mapper; - } - } - - throw new ClassNotFoundException("Cannot find implementation for " + mapperType.getName() ); - } - - private static T doGetMapper(Class clazz, ClassLoader classLoader) throws NoSuchMethodException { - try { - @SuppressWarnings( "unchecked" ) - Class implementation = (Class) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ); - Constructor constructor = implementation.getDeclaredConstructor(); - constructor.setAccessible( true ); - return constructor.newInstance(); - } - catch (ClassNotFoundException e) { - ServiceLoader loader = ServiceLoader.load( clazz, classLoader ); - - if ( loader != null ) { - for ( T mapper : loader ) { - if ( mapper != null ) { - return mapper; - } - } - } - - return null; - } - catch (InstantiationException e) { - throw new RuntimeException( e ); - } - catch (IllegalAccessException e) { - throw new RuntimeException( e ); - } - catch (InvocationTargetException e) { - throw new RuntimeException( e ); - } - } -} diff --git a/core-common/src/main/java/org/mapstruct/factory/package-info.java b/core-common/src/main/java/org/mapstruct/factory/package-info.java deleted file mode 100644 index 4ce3e2ec0f..0000000000 --- a/core-common/src/main/java/org/mapstruct/factory/package-info.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - *

- * Provides the {@link org.mapstruct.factory.Mappers} factory class for the retrieval of mapper instances if no - * explicit component model such as CDI is configured via {@link org.mapstruct.Mapper#componentModel()}. - *

- * - */ -package org.mapstruct.factory; diff --git a/core-common/src/main/java/org/mapstruct/package-info.java b/core-common/src/main/java/org/mapstruct/package-info.java deleted file mode 100644 index 8ef7ea9fce..0000000000 --- a/core-common/src/main/java/org/mapstruct/package-info.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - *

- * MapStruct is a code generator which simplifies the implementation of mappings between Java bean types by generating - * mapping code at compile time, following a convention-over-configuration approach. The generated code uses plain - * method invocations and thus is fast and type-safe. - *

- *

- * This package contains several annotations which allow to configure how mapper interfaces are generated. - *

- * - * @see MapStruct reference documentation - */ -package org.mapstruct; diff --git a/core-common/src/main/java/org/mapstruct/util/Experimental.java b/core-common/src/main/java/org/mapstruct/util/Experimental.java deleted file mode 100644 index 58cedeb932..0000000000 --- a/core-common/src/main/java/org/mapstruct/util/Experimental.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.util; - -import java.lang.annotation.Documented; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * Features that are marked with this annotation are considered experimental. - * - * @author Andreas Gudian - */ -@Documented -@Retention(RetentionPolicy.SOURCE) -public @interface Experimental { - String value() default ""; -} diff --git a/core-common/src/test/java/org/mapstruct/factory/MappersTest.java b/core-common/src/test/java/org/mapstruct/factory/MappersTest.java deleted file mode 100644 index 1a0da2626b..0000000000 --- a/core-common/src/test/java/org/mapstruct/factory/MappersTest.java +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.factory; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.mapstruct.test.model.Foo; -import org.mapstruct.test.model.SomeClass; - -/** - * Unit test for {@link Mappers}. - * - * @author Gunnar Morling - */ -public class MappersTest { - - @Test - public void shouldReturnImplementationInstance() { - - Foo mapper = Mappers.getMapper( Foo.class ); - assertThat( mapper ).isNotNull(); - } - - /** - * Checks if an implementation of a nested mapper can be found. This is a special case since - * it is named - */ - @Test - public void findsNestedMapperImpl() throws Exception { - assertThat( Mappers.getMapper( SomeClass.Foo.class ) ).isNotNull(); - assertThat( Mappers.getMapper( SomeClass.NestedClass.Foo.class ) ).isNotNull(); - } - - @Test - public void shouldReturnPackagePrivateImplementationInstance() { - assertThat( Mappers.getMapper( PackagePrivateMapper.class ) ).isNotNull(); - } -} diff --git a/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java b/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java deleted file mode 100644 index 7d5e4738af..0000000000 --- a/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.factory; - -interface PackagePrivateMapper { - -} diff --git a/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java b/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java deleted file mode 100644 index dd8ee89319..0000000000 --- a/core-common/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.factory; - -class PackagePrivateMapperImpl implements PackagePrivateMapper { -} diff --git a/core-common/src/test/java/org/mapstruct/test/model/Foo.java b/core-common/src/test/java/org/mapstruct/test/model/Foo.java deleted file mode 100644 index 1f25db3703..0000000000 --- a/core-common/src/test/java/org/mapstruct/test/model/Foo.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.test.model; - -public interface Foo { - -} diff --git a/core-common/src/test/java/org/mapstruct/test/model/FooImpl.java b/core-common/src/test/java/org/mapstruct/test/model/FooImpl.java deleted file mode 100644 index ff486c4452..0000000000 --- a/core-common/src/test/java/org/mapstruct/test/model/FooImpl.java +++ /dev/null @@ -1,23 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.test.model; - -public class FooImpl implements Foo { - -} diff --git a/core-common/src/test/java/org/mapstruct/test/model/SomeClass$FooImpl.java b/core-common/src/test/java/org/mapstruct/test/model/SomeClass$FooImpl.java deleted file mode 100644 index 0e2e0dd181..0000000000 --- a/core-common/src/test/java/org/mapstruct/test/model/SomeClass$FooImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.test.model; - -/** - * For testing naming of implementations of nested mappers (issue 611). - * - * @author Tillmann Gaida - */ -/* - * Turn off checkstyle since the underscore introduced by issue 611 violates the class naming - * convention. - */ -// CHECKSTYLE:OFF -public class SomeClass$FooImpl implements SomeClass.Foo { - -} diff --git a/core-common/src/test/java/org/mapstruct/test/model/SomeClass$NestedClass$FooImpl.java b/core-common/src/test/java/org/mapstruct/test/model/SomeClass$NestedClass$FooImpl.java deleted file mode 100644 index 27b1fec379..0000000000 --- a/core-common/src/test/java/org/mapstruct/test/model/SomeClass$NestedClass$FooImpl.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.test.model; - -/** - * For testing naming of implementations of nested mappers (issue 611). - * - * @author Tillmann Gaida - */ -/* - * Turn off checkstyle since the underscore introduced by issue 611 violates the class naming - * convention. - */ -// CHECKSTYLE:OFF -public class SomeClass$NestedClass$FooImpl implements SomeClass.NestedClass.Foo { - -} diff --git a/core-common/src/test/java/org/mapstruct/test/model/SomeClass.java b/core-common/src/test/java/org/mapstruct/test/model/SomeClass.java deleted file mode 100644 index f8fc1437e0..0000000000 --- a/core-common/src/test/java/org/mapstruct/test/model/SomeClass.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.test.model; - -/** - * The sole purpose of this class is to have a place to nest the Foo interface. - * - * @author Tillmann Gaida - */ -public class SomeClass { - public interface Foo { } - - public static class NestedClass { - public interface Foo { } - } -} diff --git a/core-jdk8/pom.xml b/core-jdk8/pom.xml index 89ffba54da..c73676192b 100644 --- a/core-jdk8/pom.xml +++ b/core-jdk8/pom.xml @@ -1,22 +1,9 @@ @@ -25,151 +12,18 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml mapstruct-jdk8 - jar MapStruct Core JDK 8 - MapStruct annotations to be used with JDK 8 and later - - - copied-common-sources - - - - - ${project.groupId} - mapstruct-common - true - - - junit - junit - test - - - org.assertj - assertj-core - test - - + Deprecated MapStruct artifact containing annotations to be used with JDK 8 and later - + Relocated to mapstruct + + + mapstruct + + - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - check-style - verify - - checkstyle - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - verify - - jar - - - - - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - - - org.codehaus.mojo - build-helper-maven-plugin - - - add-copied-common-sources - generate-sources - - add-source - - - - ${project.build.directory}/${common.sources.dir} - - - - - - - org.apache.maven.plugins - maven-resources-plugin - - - copy-resources - process-resources - - copy-resources - - - ${project.build.directory}/${common.sources.dir} - - - ${basedir}/../core-common/src/main/java - false - - - - - - copy-mapstruct-license - prepare-package - - copy-resources - - - ${project.build.directory}/classes/META-INF - - - ${basedir}/.. - false - LICENSE.txt - - - - - - - - org.apache.felix - maven-bundle-plugin - - - org.mapstruct - - - - - maven-jar-plugin - - - ${project.build.outputDirectory}/META-INF/MANIFEST.MF - - - - - com.github.siom79.japicmp - japicmp-maven-plugin - - - diff --git a/core-jdk8/src/main/java/org/mapstruct/Mapping.java b/core-jdk8/src/main/java/org/mapstruct/Mapping.java deleted file mode 100644 index 4064b7d86c..0000000000 --- a/core-jdk8/src/main/java/org/mapstruct/Mapping.java +++ /dev/null @@ -1,271 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.Annotation; -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.text.SimpleDateFormat; -import java.text.DecimalFormat; -import java.util.Date; - -/** - * Configures the mapping of one bean attribute or enum constant. - *

- * The name of the mapped attribute or constant is to be specified via {@link #target()}. For mapped bean attributes it - * is assumed by default that the attribute has the same name in the source bean. Alternatively, one of - * {@link #source()}, {@link #expression()} or {@link #constant()} can be specified to define the property source. - *

- * In addition, the attributes {@link #dateFormat()} and {@link #qualifiedBy()} may be used to further define the - * mapping. - * - *

- * IMPORTANT NOTE: the enum mapping capability is deprecated and replaced by {@link ValueMapping} it - * will be removed in subsequent versions. - * - * @author Gunnar Morling - */ -@Repeatable(Mappings.class) -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) -public @interface Mapping { - - /** - * The target name of the configured property as defined by the JavaBeans specification. The same target property - * must not be mapped more than once. - *

- * If used to map an enum constant, the name of the constant member is to be given. In this case, several values - * from the source enum may be mapped to the same value of the target enum. - * - * @return The target name of the configured property or enum constant - */ - String target(); - - /** - * The source to use for this mapping. This can either be: - *

    - *
  1. The source name of the configured property as defined by the JavaBeans specification. - *

    - * This may either be a simple property name (e.g. "address") or a dot-separated property path (e.g. "address.city" - * or "address.city.name"). In case the annotated method has several source parameters, the property name must - * qualified with the parameter name, e.g. "addressParam.city".

  2. - *
  3. When no matching property is found, MapStruct looks for a matching parameter name instead.
  4. - *
  5. When used to map an enum constant, the name of the constant member is to be given.
  6. - *
- * This attribute can not be used together with {@link #constant()} or {@link #expression()}. - * - * @return The source name of the configured property or enum constant. - */ - String source() default ""; - - /** - * A format string as processable by {@link SimpleDateFormat} if the attribute is mapped from {@code String} to - * {@link Date} or vice-versa. Will be ignored for all other attribute types and when mapping enum constants. - * - * @return A date format string as processable by {@link SimpleDateFormat}. - */ - String dateFormat() default ""; - - /** - * A format string as processable by {@link DecimalFormat} if the annotated method maps from a - * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other element types. - * - * @return A decimal format string as processable by {@link DecimalFormat}. - */ - String numberFormat() default ""; - - /** - * A constant {@link String} based on which the specified target property is to be set. - *

- * When the designated target property is of type: - *

- *
    - *
  1. primitive or boxed (e.g. {@code java.lang.Long}). - *

    - * MapStruct checks whether the primitive can be assigned as valid literal to the primitive or boxed type. - *

    - *
      - *
    • - * If possible, MapStruct assigns as literal. - *
    • - *
    • - * If not possible, MapStruct will try to apply a user defined mapping method. - *
    • - *
    - *
  2. - *
  3. other - *

    - * MapStruct handles the constant as {@code String}. The value will be converted by applying a matching method, - * type conversion method or built-in conversion. - *

    - *

  4. - *
- *

- * This attribute can not be used together with {@link #source()}, {@link #defaultValue()}, - * {@link #defaultExpression()} or {@link #expression()}. - * - * @return A constant {@code String} constant specifying the value for the designated target property - */ - String constant() default ""; - - /** - * An expression {@link String} based on which the specified target property is to be set. - *

- * Currently, Java is the only supported "expression language" and expressions must be given in form of Java - * expressions using the following format: {@code java()}. For instance the mapping: - *


-     * @Mapping(
-     *     target = "someProp",
-     *     expression = "java(new TimeAndFormat( s.getTime(), s.getFormat() ))"
-     * )
-     * 
- *

- * will cause the following target property assignment to be generated: - *

- * {@code targetBean.setSomeProp( new TimeAndFormat( s.getTime(), s.getFormat() ) )}. - *

- * Any types referenced in expressions must be given via their fully-qualified name. Alternatively, types can be - * imported via {@link Mapper#imports()}. - *

- * This attribute can not be used together with {@link #source()}, {@link #defaultValue()}, - * {@link #defaultExpression()} or {@link #constant()}. - * - * @return An expression specifying the value for the designated target property - */ - String expression() default ""; - - /** - * A defaultExpression {@link String} based on which the specified target property is to be set - * if and only if the specified source property is null. - *

- * Currently, Java is the only supported "expression language" and expressions must be given in form of Java - * expressions using the following format: {@code java()}. For instance the mapping: - *


-     * @Mapping(
-     *     target = "someProp",
-     *     defaultExpression = "java(new TimeAndFormat( s.getTime(), s.getFormat() ))"
-     * )
-     * 
- *

- * will cause the following target property assignment to be generated: - *

- * {@code targetBean.setSomeProp( new TimeAndFormat( s.getTime(), s.getFormat() ) )}. - *

- * Any types referenced in expressions must be given via their fully-qualified name. Alternatively, types can be - * imported via {@link Mapper#imports()}. - *

- * This attribute can not be used together with {@link #expression()}, {@link #defaultValue()} - * or {@link #constant()}. - * - * @return An expression specifying a defaultValue for the designated target property if the designated source - * property is null - * - * @since 1.3 - */ - String defaultExpression() default ""; - - /** - * Whether the property specified via {@link #target()} should be ignored by the generated mapping method or not. - * This can be useful when certain attributes should not be propagated from source or target or when properties in - * the target object are populated using a decorator and thus would be reported as unmapped target property by - * default. - * - * @return {@code true} if the given property should be ignored, {@code false} otherwise - */ - boolean ignore() default false; - - /** - * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple - * mapping methods (hand written or generated) qualify and thus would result in an 'Ambiguous mapping methods found' - * error. A qualifier is a custom annotation and can be placed on a hand written mapper class or a method. - * - * @return the qualifiers - */ - Class[] qualifiedBy() default { }; - - /** - * String-based form of qualifiers; When looking for a suitable mapping method for a given property, MapStruct will - * only consider those methods carrying directly or indirectly (i.e. on the class-level) a {@link Named} annotation - * for each of the specified qualifier names. - *

- * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and - * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large - * number of qualifiers as no custom annotation types are needed. - * - * @return One or more qualifier name(s) - * @see #qualifiedBy() - * @see Named - */ - String[] qualifiedByName() default { }; - - /** - * Specifies the result type of the mapping method to be used in case multiple mapping methods qualify. - * - * @return the resultType to select - */ - Class resultType() default void.class; - - /** - * One or more properties of the result type on which the mapped property depends. The generated method - * implementation will invoke the setters of the result type ordered so that the given dependency relationship(s) - * are satisfied. Useful in case one property setter depends on the state of another property of the result type. - *

- * An error will be raised in case a cycle in the dependency relationships is detected. - * - * @return the dependencies of the mapped property - */ - String[] dependsOn() default { }; - - /** - * In case the source property is {@code null}, the provided default {@link String} value is set. - *

- * When the designated target property is of type: - *

- *
    - *
  1. primitive or boxed (e.g. {@code java.lang.Long}). - *

    - * MapStruct checks whether the primitive can be assigned as valid literal to the primitive or boxed type. - *

    - *
      - *
    • - * If possible, MapStruct assigns as literal. - *
    • - *
    • - * If not possible, MapStruct will try to apply a user defined mapping method. - *
    • - *
    - *
  2. - *
  3. other - *

    - * MapStruct handles the constant as {@code String}. The value will be converted by applying a matching method, - * type conversion method or built-in conversion. - *

    - *

  4. - *
- *

- * This attribute can not be used together with {@link #constant()}, {@link #expression()} - * or {@link #defaultExpression()}. - * - * @return Default value to set in case the source property is {@code null}. - */ - String defaultValue() default ""; -} diff --git a/core-jdk8/src/main/java/org/mapstruct/Mappings.java b/core-jdk8/src/main/java/org/mapstruct/Mappings.java deleted file mode 100644 index 9bc3b1f7fa..0000000000 --- a/core-jdk8/src/main/java/org/mapstruct/Mappings.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Configures the mappings of several bean attributes. - * - * @author Gunnar Morling - */ -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) -public @interface Mappings { - - /** - * The configuration of the bean attributes. - * - * @return The configuration of the bean attributes. - */ - Mapping[] value(); -} diff --git a/core-jdk8/src/main/java/org/mapstruct/ValueMapping.java b/core-jdk8/src/main/java/org/mapstruct/ValueMapping.java deleted file mode 100644 index 5808cd5f89..0000000000 --- a/core-jdk8/src/main/java/org/mapstruct/ValueMapping.java +++ /dev/null @@ -1,126 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Repeatable; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Configures the mapping of source constant value to target constant value. - *

- * Supported mappings are - *

    - *
  1. Enumeration to Enumeration
  2. - *
- *

- * Example 1: - * - *

- * 
- * public enum OrderType { RETAIL, B2B, EXTRA, STANDARD, NORMAL }
- *
- * public enum ExternalOrderType { RETAIL, B2B, SPECIAL, DEFAULT }
- *
- * @ValueMapping(source = "EXTRA", target = "SPECIAL"),
- * @ValueMapping(source = "STANDARD", target = "DEFAULT"),
- * @ValueMapping(source = "NORMAL", target = "DEFAULT")
- * ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
- * 
- * Mapping result:
- * +---------------------+----------------------------+
- * | OrderType           | ExternalOrderType          |
- * +---------------------+----------------------------+
- * | null                | null                       |
- * | OrderType.EXTRA     | ExternalOrderType.SPECIAL  |
- * | OrderType.STANDARD  | ExternalOrderType.DEFAULT  |
- * | OrderType.NORMAL    | ExternalOrderType.DEFAULT  |
- * | OrderType.RETAIL    | ExternalOrderType.RETAIL   |
- * | OrderType.B2B       | ExternalOrderType.B2B      |
- * +---------------------+----------------------------+
- * 
- * - * MapStruct will WARN on incomplete mappings. However, if for some reason no match is found an - * {@link java.lang.IllegalStateException} will be thrown. - *

- * Example 2: - * - *

- * 
- * @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ),
- * @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ),
- * @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" )
- * ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
- * 
- * Mapping result:
- * +---------------------+----------------------------+
- * | OrderType           | ExternalOrderType          |
- * +---------------------+----------------------------+
- * | null                | ExternalOrderType.DEFAULT  |
- * | OrderType.STANDARD  | null                       |
- * | OrderType.RETAIL    | ExternalOrderType.RETAIL   |
- * | OrderType.B2B       | ExternalOrderType.B2B      |
- * | OrderType.NORMAL    | ExternalOrderType.SPECIAL  |
- * | OrderType.EXTRA     | ExternalOrderType.SPECIAL  |
- * +---------------------+----------------------------+
- * 
- * - * @author Sjaak Derksen - */ -@Repeatable(ValueMappings.class) -@Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) -public @interface ValueMapping { - /** - * The source value constant to use for this mapping. - * - *

- * Valid values: - *

    - *
  1. enum constant name
  2. - *
  3. {@link MappingConstants#NULL}
  4. - *
  5. {@link MappingConstants#ANY_REMAINING}
  6. - *
  7. {@link MappingConstants#ANY_UNMAPPED}
  8. - *
- *

- * NOTE:When using <ANY_REMAINING>, MapStruct will perform the normal name based mapping, in which - * source is mapped to target based on enum identifier equality. Using <ANY_UNMAPPED> will not apply name - * based mapping. - * - * @return The source value. - */ - String source(); - - /** - * The target value constant to use for this mapping. - * - *

- * Valid values: - *

    - *
  1. enum constant name
  2. - *
  3. {@link MappingConstants#NULL}
  4. - *
- * - * @return The target value. - */ - String target(); - -} diff --git a/core-jdk8/src/main/java/org/mapstruct/ValueMappings.java b/core-jdk8/src/main/java/org/mapstruct/ValueMappings.java deleted file mode 100644 index 5c720e834d..0000000000 --- a/core-jdk8/src/main/java/org/mapstruct/ValueMappings.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Constructs a set of value (constant) mappings. - * - * @author Sjaak Derksen - */ -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface ValueMappings { - - ValueMapping[] value(); - -} diff --git a/core/pom.xml b/core/pom.xml index 1f4a7a65df..e62d5e4682 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -1,22 +1,9 @@ @@ -25,7 +12,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml @@ -33,19 +20,10 @@ jar MapStruct Core - - copied-common-sources - - - ${project.groupId} - mapstruct-common - true - - - junit - junit + org.junit.jupiter + junit-jupiter test @@ -83,44 +61,10 @@ - - org.codehaus.mojo - build-helper-maven-plugin - - - add-copied-common-sources - generate-sources - - add-source - - - - ${project.build.directory}/${common.sources.dir} - - - - - org.apache.maven.plugins maven-resources-plugin - - copy-resources - process-resources - - copy-resources - - - ${project.build.directory}/${common.sources.dir} - - - ${basedir}/../core-common/src/main/java - false - - - - copy-mapstruct-license prepare-package diff --git a/core-common/src/main/java/org/mapstruct/AfterMapping.java b/core/src/main/java/org/mapstruct/AfterMapping.java similarity index 81% rename from core-common/src/main/java/org/mapstruct/AfterMapping.java rename to core/src/main/java/org/mapstruct/AfterMapping.java index f6d8350ea5..a76eebdcba 100644 --- a/core-common/src/main/java/org/mapstruct/AfterMapping.java +++ b/core/src/main/java/org/mapstruct/AfterMapping.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; diff --git a/core/src/main/java/org/mapstruct/AnnotateWith.java b/core/src/main/java/org/mapstruct/AnnotateWith.java new file mode 100644 index 0000000000..79b7cec98c --- /dev/null +++ b/core/src/main/java/org/mapstruct/AnnotateWith.java @@ -0,0 +1,183 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * This can be used to have mapstruct generate additional annotations on classes/methods. + *

+ * Examples based on the spring framework annotations. + *

+ * Marking a class as `Lazy`: + * + *

+ * @AnnotateWith( value = Lazy.class )
+ * @Mapper
+ * public interface FooMapper {
+ *     // mapper code
+ * }
+ * 
+ * + * The following code would be generated: + * + *

+ * @Lazy
+ * public class FooMapperImpl implements FooMapper {
+ *     // mapper code
+ * }
+ * 
+ * Setting the profile on the generated implementation: + * + *

+ * @AnnotateWith( value = Profile.class, elements = @AnnotateWith.Element( strings = "prod" ) )
+ * @Mapper
+ * public interface FooMapper {
+ *     // mapper code
+ * }
+ * 
+ * + * The following code would be generated: + * + *

+ * @Profile( value = "prod" )
+ * public class FooMapperImpl implements FooMapper {
+ *     // mapper code
+ * }
+ * 
+ * + * @author Ben Zegveld + * @since 1.6 + */ +@Repeatable( AnnotateWiths.class ) +@Retention( CLASS ) +@Target( { TYPE, METHOD, ANNOTATION_TYPE } ) +public @interface AnnotateWith { + + /** + * The annotation class that needs to be added. + * + * @return the annotation class that needs to be added. + */ + Class value(); + + /** + * The annotation elements that are to be applied to the annotation that should be added. + * + * @return the annotation elements that are to be applied to this annotation. + */ + Element[] elements() default {}; + + /** + * Used in combination with {@link AnnotateWith} to configure the annotation elements. Only 1 value type may be used + * within the same annotation at a time. For example mixing shorts and ints is not allowed. + * + * @author Ben Zegveld + * @since 1.6 + */ + @interface Element { + /** + * The name of the annotation element. + * + * @return name of the annotation element. + */ + String name() default "value"; + + /** + * cannot be used in conjunction with other value fields. + * + * @return short value(s) for the annotation element. + */ + short[] shorts() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return byte value(s) for the annotation element. + */ + byte[] bytes() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return int value(s) for the annotation element. + */ + int[] ints() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return long value(s) for the annotation element. + */ + long[] longs() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return float value(s) for the annotation element. + */ + float[] floats() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return double value(s) for the annotation element. + */ + double[] doubles() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return char value(s) for the annotation element. + */ + char[] chars() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return boolean value(s) for the annotation element. + */ + boolean[] booleans() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return string value(s) for the annotation element. + */ + String[] strings() default {}; + + /** + * cannot be used in conjunction with other value fields. + * + * @return class value(s) for the annotation element. + */ + Class[] classes() default {}; + + /** + * only used in conjunction with the {@link #enums()} annotation element. + * + * @return the class of the enum. + */ + Class> enumClass() default NullEnum.class; + + /** + * cannot be used in conjunction with other value fields. {@link #enumClass()} is also required when using + * {@link #enums()} + * + * @return enum value(s) for the annotation element. + */ + String[] enums() default {}; + + } +} diff --git a/core/src/main/java/org/mapstruct/AnnotateWiths.java b/core/src/main/java/org/mapstruct/AnnotateWiths.java new file mode 100644 index 0000000000..5e86ad9a19 --- /dev/null +++ b/core/src/main/java/org/mapstruct/AnnotateWiths.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.CLASS; + +/** + * This can be used to have mapstruct generate additional annotations on classes/methods. + * + * @author Ben Zegveld + * @since 1.6 + */ +@Retention( CLASS ) +@Target( { TYPE, METHOD } ) +public @interface AnnotateWiths { + + /** + * The configuration of the additional annotations. + * + * @return The configuration of the additional annotations. + */ + AnnotateWith[] value(); +} diff --git a/core/src/main/java/org/mapstruct/BeanMapping.java b/core/src/main/java/org/mapstruct/BeanMapping.java new file mode 100644 index 0000000000..309458f861 --- /dev/null +++ b/core/src/main/java/org/mapstruct/BeanMapping.java @@ -0,0 +1,227 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.control.MappingControl; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; +import static org.mapstruct.SubclassExhaustiveStrategy.COMPILE_ERROR; + +/** + * Configures the mapping between two bean types. + *

+ * Unless otherwise specified these properties are inherited to the generated bean mapping methods. + *

+ * Either {@link #resultType()}, {@link #qualifiedBy()} or {@link #nullValueMappingStrategy()} must be specified. + *

+ *

Example: Determining the result type

+ *

+ * // When result types have an inheritance relation, selecting either mapping method {@link Mapping} or factory method
+ * // {@link BeanMapping} can be become ambiguous. Parameter  {@link BeanMapping#resultType()} can be used.
+ * public class FruitFactory {
+ *     public Apple createApple() {
+ *         return new Apple();
+ *     }
+ *     public Orange createOrange() {
+ *         return new Orange();
+ *     }
+ * }
+ * @Mapper(uses = FruitFactory.class)
+ * public interface FruitMapper {
+ *     @BeanMapping(resultType = Apple.class)
+ *     Fruit toFruit(FruitDto fruitDto);
+ * }
+ * 
+ *

+ * // generates
+ * public class FruitMapperImpl implements FruitMapper {
+ *      @Override
+ *      public Fruit toFruit(FruitDto fruitDto) {
+ *          Apple fruit = fruitFactory.createApple();
+ *          // ...
+ *      }
+ * }
+ * 
+ * + * @author Sjaak Derksen + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface BeanMapping { + + /** + * Specifies the result type of the factory method to be used in case several factory methods qualify. + *

+ * NOTE: This property is not inherited to generated mapping methods + * + * @return the resultType to select + */ + Class resultType() default void.class; + + /** + * A qualifier can be specified to aid the selection process of a suitable factory method or filtering applicable + * {@code @}{@link BeforeMapping} / {@code @}{@link AfterMapping} methods. This is useful in case multiple factory + * method (hand written of internal) qualify and result in an 'Ambiguous factory methods' error. + *

+ * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. + * + * @return the qualifiers + * @see Qualifier + */ + Class[] qualifiedBy() default {}; + + /** + * Similar to {@link #qualifiedBy()}, but used in combination with {@code @}{@link Named} in case no custom + * qualifier annotation is defined. + * + * @return the qualifiers + * @see Named + */ + String[] qualifiedByName() default { }; + + /** + * The strategy to be applied when {@code null} is passed as source bean argument value to this bean mapping. If no + * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or + * {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL} + * by default. + * + * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping. + */ + NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when a source bean property is {@code null} or not present. If no strategy is + * configured, the strategy given via {@link MapperConfig#nullValuePropertyMappingStrategy()} or + * {@link Mapper#nullValuePropertyMappingStrategy()} will be applied, + * {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.3 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() + default NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link MapperConfig}, {@link Mapper} or {@link Mapping}. + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * Determines how to handle missing implementation for super classes when using the {@link SubclassMapping}. + * + * Overrides the setting on {@link MapperConfig} and {@link Mapper}. + * + * @return strategy to handle missing implementation combined with {@link SubclassMappings}. + * + * @since 1.5 + */ + SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR; + + /** + * Specifies the exception type to be thrown when a missing subclass implementation is detected + * in combination with {@link SubclassMappings}, based on the {@link #subclassExhaustiveStrategy()}. + *

+ * This exception will only be thrown when the {@code subclassExhaustiveStrategy} is set to + * {@link SubclassExhaustiveStrategy#RUNTIME_EXCEPTION}. + * + * @return the exception class to throw when missing implementations are found. + * Defaults to {@link IllegalArgumentException}. + */ + Class subclassExhaustiveException() default IllegalArgumentException.class; + + /** + * Default ignore all mappings. All mappings have to be defined manually. No automatic mapping will take place. No + * warning will be issued on missing source or target properties. + * + * @return The ignore strategy (default false). + * + * @since 1.3 + */ + boolean ignoreByDefault() default false; + + /** + * Unmapped source properties to be ignored. This could be used when {@link ReportingPolicy#WARN} + * or {@link ReportingPolicy#ERROR} is used for {@link Mapper#unmappedSourcePolicy()} or + * {@link MapperConfig#unmappedSourcePolicy()}. Listed properties will be ignored when composing the unmapped + * source properties report. + *

+ * NOTE: This does not support ignoring nested source properties + *

+ * NOTE: This property is not inherited to generated mapping methods + * + * @return The source properties that should be ignored when performing a report + * + * @since 1.3 + */ + String[] ignoreUnmappedSourceProperties() default {}; + + /** + * How unmapped properties of the source type of a mapping should be reported. + * If no policy is configured, the policy given via {@link MapperConfig#unmappedSourcePolicy()} or + * {@link Mapper#unmappedSourcePolicy()} will be applied, using {@link ReportingPolicy#IGNORE} by default. + * + * @return The reporting policy for unmapped source properties. + * + * @since 1.6 + */ + ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE; + + /** + * How unmapped properties of the target type of a mapping should be reported. + * If no policy is configured, the policy given via {@link MapperConfig#unmappedTargetPolicy()} or + * {@link Mapper#unmappedTargetPolicy()} will be applied, using {@link ReportingPolicy#WARN} by default. + * + * @return The reporting policy for unmapped target properties. + * + * @since 1.5 + */ + ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN; + + /** + * The information that should be used for the builder mappings. This can be used to define custom build methods + * for the builder strategy that one uses. + * + * If no builder is defined the builder given via {@link MapperConfig#builder()} or {@link Mapper#builder()} + * will be applied. + *

+ * NOTE: In case no builder is defined here, in {@link Mapper} or {@link MapperConfig} and there is a single + * build method, then that method would be used. + *

+ * If the builder is defined and there is a single method that does not match the name of the finisher than + * a compile error will occurs + * + * @return the builder information for the method level + * + * @since 1.3 + */ + Builder builder() default @Builder; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + +} diff --git a/core-common/src/main/java/org/mapstruct/BeforeMapping.java b/core/src/main/java/org/mapstruct/BeforeMapping.java similarity index 82% rename from core-common/src/main/java/org/mapstruct/BeforeMapping.java rename to core/src/main/java/org/mapstruct/BeforeMapping.java index 626e918ed8..0e296e71a7 100644 --- a/core-common/src/main/java/org/mapstruct/BeforeMapping.java +++ b/core/src/main/java/org/mapstruct/BeforeMapping.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; diff --git a/core/src/main/java/org/mapstruct/Builder.java b/core/src/main/java/org/mapstruct/Builder.java new file mode 100644 index 0000000000..449c4ac05c --- /dev/null +++ b/core/src/main/java/org/mapstruct/Builder.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.util.Experimental; + +/** + * Configuration of builders, e.g. the name of the final build method. + * + *

+ * Example: Using builder + *

+ *

+ * // Mapper
+ * @Mapper
+ * public interface SimpleBuilderMapper {
+ *      @Mapping(target = "name", source = "fullName"),
+ *      @Mapping(target = "job", constant = "programmer"),
+ *      SimpleImmutablePerson toImmutable(SimpleMutablePerson source);
+ * }
+ * 
+ *

+ * // generates
+ * @Override
+ * public SimpleImmutablePerson toImmutable(SimpleMutablePerson source) {
+ *      // name method can be changed with parameter {@link #buildMethod()}
+ *      Builder simpleImmutablePerson = SimpleImmutablePerson.builder();
+ *      simpleImmutablePerson.name( source.getFullName() );
+ *      simpleImmutablePerson.age( source.getAge() );
+ *      simpleImmutablePerson.address( source.getAddress() );
+ *      simpleImmutablePerson.job( "programmer" );
+ *      // ...
+ * }
+ * 
+ * + * @author Filip Hrisafov + * + * @since 1.3 + */ +@Retention(RetentionPolicy.CLASS) +@Target({}) +@Experimental +public @interface Builder { + + /** + * The name of the build method that needs to be invoked on the builder to create the type to be build + * + * @return the method that needs to tbe invoked on the builder + */ + String buildMethod() default "build"; + + /** + * Toggling builders on / off. Builders are sometimes used solely for unit testing (fluent testdata) + * MapStruct will need to use the regular getters /setters in that case. + * + * @return when true, no builder patterns will be applied + */ + boolean disableBuilder() default false; +} diff --git a/core/src/main/java/org/mapstruct/ClassAccessibility.java b/core/src/main/java/org/mapstruct/ClassAccessibility.java new file mode 100644 index 0000000000..c533b1ea32 --- /dev/null +++ b/core/src/main/java/org/mapstruct/ClassAccessibility.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Determines whether a generated Mapper implementation class will be declared {@code public} or not. + * + * @author Raimund Klein + * + * @since 1.7.0 + */ +public enum ClassAccessibility { + /** + * The generated Mapper will have the same modifier ({@code public} or none) as the annotated class or interface. + */ + DEFAULT, + /** + * The generated Mapper will be declared {@code public}. + */ + PUBLIC, + /** + * The generated Mapper will have no visibility modifier ("package-private"). + */ + PACKAGE_PRIVATE +} diff --git a/core/src/main/java/org/mapstruct/CollectionMappingStrategy.java b/core/src/main/java/org/mapstruct/CollectionMappingStrategy.java new file mode 100644 index 0000000000..0ea3ee7df5 --- /dev/null +++ b/core/src/main/java/org/mapstruct/CollectionMappingStrategy.java @@ -0,0 +1,99 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for propagating the value of collection-typed properties from source to target. + *

+ * In the table below, the dash {@code -} indicates a property name. + * Next, the trailing {@code s} indicates the plural form. + * The table explains the options and how they are applied to the presence / absence of a + * {@code set-s}, {@code add-} and / or {@code get-s} method on the target object. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Collection mapping strategy options
OptionOnly target set-s AvailableOnly target add- AvailableBoth set-s/add- AvailableNo set-s/add- AvailableExisting Target ({@code @TargetType})
{@link #ACCESSOR_ONLY}set-sget-sset-sget-sget-s
{@link #SETTER_PREFERRED}set-sadd-set-sget-sget-s
{@link #ADDER_PREFERRED}set-sadd-add-get-sget-s
{@link #TARGET_IMMUTABLE}set-sexceptionset-sexceptionset-s
+ * + * @author Sjaak Derksen + */ +public enum CollectionMappingStrategy { + + /** + * The setter of the target property will be used to propagate the value: + * {@code orderDto.setOrderLines(order.getOrderLines)}. + *

+ * If no setter is available but a getter method, this will be used, under the assumption it has been initialized: + * {@code orderDto.getOrderLines().addAll(order.getOrderLines)}. This will also be the case when using + * {@link MappingTarget} (updating existing instances). + */ + ACCESSOR_ONLY, + + /** + * If present, the setter of the target property will be used to propagate the value: + * {@code orderDto.setOrderLines(order.getOrderLines)}. + *

+ * If no setter but and adder method is present, that adder will be invoked for each element of the source + * collection: {@code order.addOrderLine(orderLine() )}. + *

+ * If neither a setter nor an adder method but a getter for the target property is present, that getter will be + * used, assuming it returns an initialized collection: If no setter is available, MapStruct will first look for an + * adder method before resorting to a getter. + */ + SETTER_PREFERRED, + + /** + * Identical to {@link #SETTER_PREFERRED}, only that adder methods will be preferred over setter methods, if both + * are present for a given collection-typed property. + */ + ADDER_PREFERRED, + + /** + * Identical to {@link #SETTER_PREFERRED}, however the target collection will not be cleared and accessed via + * addAll in case of updating existing bean instances, see: {@link MappingTarget}. + * + * Instead the target accessor (e.g. set) will be used on the target bean to set the collection. + */ + TARGET_IMMUTABLE; +} diff --git a/core/src/main/java/org/mapstruct/Condition.java b/core/src/main/java/org/mapstruct/Condition.java new file mode 100644 index 0000000000..8abe2f817c --- /dev/null +++ b/core/src/main/java/org/mapstruct/Condition.java @@ -0,0 +1,99 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks a method as a presence check method to check for presence in beans + * or it can be used to define additional check methods for something like source parameters. + *

+ * By default, bean properties are checked against {@code null} or using a presence check method in the source bean. + * If a presence check method is available then it will be used instead. + *

+ * Presence check methods have to return {@code boolean}. + * The following parameters are accepted for the presence check methods: + *

    + *
  • The parameter with the value of the source property. + * e.g. the value given by calling {@code getName()} for the name property of the source bean + * - only possible when using the {@link ConditionStrategy#PROPERTIES} + *
  • + *
  • The mapping source parameter
  • + *
  • {@code @}{@link Context} parameter
  • + *
  • + * {@code @}{@link TargetPropertyName} parameter - + * only possible when using the {@link ConditionStrategy#PROPERTIES} + *
  • + *
  • + * {@code @}{@link SourcePropertyName} parameter - + * only possible when using the {@link ConditionStrategy#PROPERTIES} + *
  • + *
+ * + * Note: The usage of this annotation is mandatory + * for a method to be considered as a presence check method. + * + *

+ * public class PresenceCheckUtils {
+ *
+ *   @Condition
+ *   public static boolean isNotEmpty(String value) {
+ *      return value != null && !value.isEmpty();
+ *   }
+ * }
+ *
+ * @Mapper(uses = PresenceCheckUtils.class)
+ * public interface MovieMapper {
+ *
+ *     MovieDto map(Movie movie);
+ * }
+ * 
+ *

+ * The following implementation of {@code MovieMapper} will be generated: + * + *


+ * public class MovieMapperImpl implements MovieMapper {
+ *
+ *     @Override
+ *     public MovieDto map(Movie movie) {
+ *         if ( movie == null ) {
+ *             return null;
+ *         }
+ *
+ *         MovieDto movieDto = new MovieDto();
+ *
+ *         if ( PresenceCheckUtils.isNotEmpty( movie.getTitle() ) ) {
+ *             movieDto.setTitle( movie.getTitle() );
+ *         }
+ *
+ *         return movieDto;
+ *     }
+ * }
+ * 
+ *

+ * This annotation can also be used as a meta-annotation to define the condition strategy. + * + * @author Filip Hrisafov + * @see SourceParameterCondition + * @since 1.5 + */ +@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.CLASS) +public @interface Condition { + + /** + * The condition strategy for the condition. + * This determines whether the condition is applied to properties, parameters, or both. + * + * @return the places where the condition should apply to + * @since 1.6 + */ + ConditionStrategy[] appliesTo() default ConditionStrategy.PROPERTIES; + +} diff --git a/core/src/main/java/org/mapstruct/ConditionStrategy.java b/core/src/main/java/org/mapstruct/ConditionStrategy.java new file mode 100644 index 0000000000..6b042017c2 --- /dev/null +++ b/core/src/main/java/org/mapstruct/ConditionStrategy.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for defining what to what a condition (check) method is applied to + * + * @author Filip Hrisafov + * @since 1.6 + */ +public enum ConditionStrategy { + /** + * The condition method should be applied whether a property should be mapped. + */ + PROPERTIES, + /** + * The condition method should be applied to check if a source parameters should be mapped. + */ + SOURCE_PARAMETERS, +} diff --git a/core-common/src/main/java/org/mapstruct/Context.java b/core/src/main/java/org/mapstruct/Context.java similarity index 88% rename from core-common/src/main/java/org/mapstruct/Context.java rename to core/src/main/java/org/mapstruct/Context.java index 7d5d922cb3..58f606a038 100644 --- a/core-common/src/main/java/org/mapstruct/Context.java +++ b/core/src/main/java/org/mapstruct/Context.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; diff --git a/core-common/src/main/java/org/mapstruct/DecoratedWith.java b/core/src/main/java/org/mapstruct/DecoratedWith.java similarity index 80% rename from core-common/src/main/java/org/mapstruct/DecoratedWith.java rename to core/src/main/java/org/mapstruct/DecoratedWith.java index 632f63b749..3db27b2a0a 100644 --- a/core-common/src/main/java/org/mapstruct/DecoratedWith.java +++ b/core/src/main/java/org/mapstruct/DecoratedWith.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; @@ -35,9 +22,7 @@ *

* NOTE: This annotation is not supported for the component model {@code cdi}. Use CDI's own * {@code @Decorator} feature instead. - *

- * NOTE: The decorator feature when used with component model {@code jsr330} is considered experimental - * and it may change in future releases. + *

*

Examples

*

* For the examples below, consider the following mapper declaration: @@ -118,12 +103,12 @@ * private PersonMapper personMapper; // injects the decorator, with the injected original mapper * * - *

3. Component model 'jsr330'

+ *

3. Component model 'jsr330' or 'jakarta'

*

Referencing the original mapper

*

- * JSR 330 doesn't specify qualifiers and only allows to specifically name the beans. Hence, the generated - * implementation of the original mapper is annotated with - * {@code @javax.inject.Named("fully-qualified-name-of-generated-impl")} and {@code @Singleton} (please note that when + * JSR 330 / Jakarta Inject doesn't specify qualifiers and only allows to specifically name the beans. Hence, + * the generated implementation of the original mapper is annotated with + * {@code @Named("fully-qualified-name-of-generated-impl")} and {@code @Singleton} (please note that when * using a decorator, the class name of the mapper implementation ends with an underscore). To inject that bean in your * decorator, add the same annotation to the delegate field (e.g. by copy/pasting it from the generated class): * @@ -155,12 +140,11 @@ * @javax.inject.Named * private PersonMapper personMapper; // injects the decorator, with the injected original mapper * - *

* * @author Gunnar Morling */ @Target(ElementType.TYPE) -@Retention(RetentionPolicy.SOURCE) +@Retention(RetentionPolicy.CLASS) public @interface DecoratedWith { /** diff --git a/core/src/main/java/org/mapstruct/EnumMapping.java b/core/src/main/java/org/mapstruct/EnumMapping.java new file mode 100644 index 0000000000..375f969b01 --- /dev/null +++ b/core/src/main/java/org/mapstruct/EnumMapping.java @@ -0,0 +1,156 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Configured the mapping between two value types. + *

Example: Using a suffix for enums

+ *

+ * public enum CheeseType {
+ *     BRIE,
+ *     ROQUEFORT
+ * }
+ *
+ * public enum CheeseTypeSuffixed {
+ *     BRIE_TYPE,
+ *     ROQUEFORT_TYPE
+ * }
+ *
+ * @Mapper
+ * public interface CheeseMapper {
+ *
+ *     @EnumMapping(nameTransformationStrategy = "suffix", configuration = "_TYPE")
+ *     CheeseTypeSuffixed map(Cheese cheese);
+ *
+ *     @InheritInverseConfiguration
+ *     Cheese map(CheeseTypeSuffixed cheese);
+ *
+ * }
+ * 
+ *

+ * // generates
+ * public class CheeseMapperImpl implements CheeseMapper {
+ *
+ *     @Override
+ *     public CheeseTypeSuffixed map(Cheese cheese) {
+ *         if ( cheese == null ) {
+ *             return null;
+ *         }
+ *
+ *         CheeseTypeSuffixed cheeseTypeSuffixed;
+ *
+ *         switch ( cheese ) {
+ *             case BRIE:
+ *                 cheeseTypeSuffixed = CheeseTypeSuffixed.BRIE_TYPE;
+ *                 break;
+ *             case ROQUEFORT:
+ *                 cheeseTypeSuffixed = CheeseTypeSuffixed.ROQUEFORT_TYPE;
+ *                 break;
+ *             default:
+ *                 throw new IllegalArgumentException( "Unexpected enum constant: " + cheese );
+ *         }
+ *
+ *         return cheeseTypeSuffixed;
+ *     }
+ *
+ *     @Override
+ *     public Cheese map(CheeseTypeSuffixed cheese) {
+ *         if ( cheese == null ) {
+ *             return null;
+ *         }
+ *
+ *         CheeseType cheeseType;
+ *
+ *         switch ( cheese ) {
+ *             case BRIE_TYPE:
+ *                 cheeseType = CheeseType.BRIE;
+ *                 break;
+ *             case ROQUEFORT_TYPE:
+ *                 cheeseType = CheeseType.ROQUEFORT;
+ *                 break;
+ *             default:
+ *                 throw new IllegalArgumentException( "Unexpected enum constant: " + cheese );
+ *         }
+ *
+ *         return cheeseType;
+ *     }
+ * }
+ * 
+ * + * @author Filip Hrisafov + * @since 1.4 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface EnumMapping { + + /** + * Specifies the name transformation strategy that should be used for implicit mapping between enums. + * Known strategies are: + *
    + *
  • {@link MappingConstants#SUFFIX_TRANSFORMATION} - applies the given {@link #configuration()} as a + * suffix to the source enum
  • + *
  • {@link MappingConstants#STRIP_SUFFIX_TRANSFORMATION} - strips the given {@link #configuration()} + * from the end of the source enum
  • + *
  • {@link MappingConstants#PREFIX_TRANSFORMATION} - applies the given {@link #configuration()} as a + * prefix to the source enum
  • + *
  • {@link MappingConstants#STRIP_PREFIX_TRANSFORMATION} - strips the given {@link #configuration()} from + * the start of the source enum
  • + *
  • + * {@link MappingConstants#CASE_TRANSFORMATION} - applies the given {@link #configuration()} case + * transformation to the source enum. Supported configurations are: + *
      + *
    • upper - Performs upper case transformation to the source enum
    • + *
    • lower - Performs lower case transformation to the source enum
    • + *
    • + * capital - Performs capitalisation of the first character of every word in the source enum + * and everything else to lower case. A word is split by "_". + *
    • + *
    + *
  • + *
+ * + * It is possible to use custom name transformation strategies by implementing the {@code + * EnumTransformationStrategy} SPI. + * + * @return the name transformation strategy + */ + String nameTransformationStrategy() default ""; + + /** + * The configuration that should be passed on the appropriate name transformation strategy. + * e.g. a suffix that should be applied to the source enum when doing name based mapping. + * + * @return the configuration to use + */ + String configuration() default ""; + + /** + * Exception that should be thrown by the generated code if no mapping matches. + * If no exception is configured, the exception given via {@link MapperConfig#unexpectedValueMappingException()} or + * {@link Mapper#unexpectedValueMappingException()} will be used, using {@link IllegalArgumentException} by default. + * + *

+ * Note: + *

    + *
  • + * The defined exception should at least have a constructor with a {@link String} parameter. + *
  • + *
  • + * If the defined exception is a checked exception then the enum mapping methods should have that exception + * in the throws clause. + *
  • + *
+ * + * @return the exception that should be used in the generated code + */ + Class unexpectedValueMappingException() default IllegalArgumentException.class; +} diff --git a/core/src/main/java/org/mapstruct/Ignored.java b/core/src/main/java/org/mapstruct/Ignored.java new file mode 100644 index 0000000000..47e4961f43 --- /dev/null +++ b/core/src/main/java/org/mapstruct/Ignored.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Configures the ignored of one bean attribute. + * + *

+ * The name all attributes of for ignored is to be specified via {@link #targets()}. + *

+ * + *

+ * Example 1: Implicitly mapping fields with the same name: + *

+ * + *

+ * // We need ignored Human.name and Human.lastName
+ * // we can use @Ignored with parameters "name", "lastName" {@link #targets()}
+ * @Mapper
+ * public interface HumanMapper {
+ *    @Ignored( targets = { "name", "lastName" } )
+ *    HumanDto toHumanDto(Human human)
+ * }
+ * 
+ *

+ * // generates:
+ * @Override
+ * public HumanDto toHumanDto(Human human) {
+ *    humanDto.setFullName( human.getFullName() );
+ *    // ...
+ * }
+ * 
+ * + * @author Ivashin Aleksey + */ +@Repeatable(IgnoredList.class) +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) +public @interface Ignored { + + /** + * Whether the specified properties should be ignored by the generated mapping method. + * This can be useful when certain attributes should not be propagated from source to target or when properties in + * the target object are populated using a decorator and thus would be reported as unmapped target property by + * default. + * + * @return The target names of the configured properties that should be ignored + */ + String[] targets(); + + /** + * The prefix that should be applied to all the properties specified via {@link #targets()}. + * + * @return The target prefix to be applied to the defined properties + */ + String prefix() default ""; + +} diff --git a/core/src/main/java/org/mapstruct/IgnoredList.java b/core/src/main/java/org/mapstruct/IgnoredList.java new file mode 100644 index 0000000000..e47db6bac7 --- /dev/null +++ b/core/src/main/java/org/mapstruct/IgnoredList.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Configures the ignored list for several bean attributes. + *

+ * TIP: When using Java 8 or later, you can omit the {@code @IgnoredList} + * wrapper annotation and directly specify several {@code @Ignored} annotations on one method. + * + *

These two examples are equal. + *

+ *

+ * // before Java 8
+ * @Mapper
+ * public interface MyMapper {
+ *     @IgnoredList({
+ *         @Ignored(targets = { "firstProperty" } ),
+ *         @Ignored(targets = { "secondProperty" } )
+ *     })
+ *     HumanDto toHumanDto(Human human);
+ * }
+ * 
+ *

+ * // Java 8 and later
+ * @Mapper
+ * public interface MyMapper {
+ *     @Ignored(targets = { "firstProperty" } ),
+ *     @Ignored(targets = { "secondProperty" } )
+ *     HumanDto toHumanDto(Human human);
+ * }
+ * 
+ * + * @author Ivashin Aleksey + */ +@Retention(RetentionPolicy.CLASS) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +public @interface IgnoredList { + + /** + * The configuration of the bean attributes. + * + * @return The configuration of the bean attributes. + */ + Ignored[] value(); +} diff --git a/core/src/main/java/org/mapstruct/InheritConfiguration.java b/core/src/main/java/org/mapstruct/InheritConfiguration.java new file mode 100644 index 0000000000..0d1bf0b38f --- /dev/null +++ b/core/src/main/java/org/mapstruct/InheritConfiguration.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Advises the code generator to apply the configuration (as given via {@link Mapping}, {@link IterableMapping} etc.) + * from another mapping method (declared on the same mapper type) or prototype method (declared on a mapper config class + * referenced via {@link Mapper#config()}) to the annotated method as well. + *

+ * If no method can be identified unambiguously as configuration source (i.e. several candidate methods with matching + * source and target type exist), the name of the method to inherit from must be specified via {@link #name()}. + *

+ * {@link Mapping#expression()}, {@link Mapping#constant()}, {@link Mapping#defaultExpression()} and + * {@link Mapping#defaultValue()} are not inverse inherited + * + *

+ * A typical use case is annotating an update method so it inherits all mappings from a corresponding "standard" mapping + * method: + * + *

+ * 
+ * @Mappings({
+ *     @Mapping(target="make", source="brand"),
+ *     @Mapping(target="seatCount", source="numberOfSeats")
+ * })
+ * CarDto carToCarDto(Car car);
+ *
+ * @InheritConfiguration
+ * void updateCarDto(Car car, @MappingTarget CarDto carDto);
+ * 
+ * 
+ * + * @author Sjaak Derksen + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface InheritConfiguration { + + /** + * The name of the mapping method to inherit the mappings from. Needs only to be specified in case more than one + * method with matching source and target type exists. + * + * @return The name of the mapping method to inherit the mappings from. + */ + String name() default ""; +} diff --git a/core/src/main/java/org/mapstruct/InheritInverseConfiguration.java b/core/src/main/java/org/mapstruct/InheritInverseConfiguration.java new file mode 100644 index 0000000000..b659b7f37a --- /dev/null +++ b/core/src/main/java/org/mapstruct/InheritInverseConfiguration.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Advises the code generator to apply all the {@link Mapping}s from an inverse mapping method to the annotated method + * as well. An inverse mapping method is a method which has the annotated method's source type as target type (return + * type or indicated through a parameter annotated with {@link MappingTarget}) and the annotated method's target type as + * source type. + *

+ * Any mappings given on the annotated method itself are added to those mappings inherited from the inverse method. In + * case of a conflict local mappings take precedence over inherited mappings. + *

+ * If more than one matching inverse method exists, the name of the method to inherit the configuration from must be + * specified via {@link #name()} + *

+ * {@link Mapping#expression()}, {@link Mapping#constant()}, {@link Mapping#defaultExpression()} and + * {@link Mapping#defaultValue()} are not inverse inherited + * + *

+ * Examples + *

+ *

+ * @Mapper
+ * public interface HumanMapper {
+ *      Human toHuman(HumanDto humanDto);
+ *      @InheritInverseConfiguration
+ *      HumanDto toHumanDto(Human human);
+ * }
+ * 
+ *

+ * // generates
+ * public class HumanMapperImpl implements HumanMapper {
+ *      @Override
+ *      public Human toHuman(HumanDto humanDto) {
+ *          if ( humanDto == null ) {
+ *              return null;
+ *           }
+ *          Human human = new Human();
+ *          human.setName( humanDto.getName() );
+ *          return human;
+ *      }
+ *      @Override
+ *      public HumanDto toHumanDto(Human human) {
+ *          if ( human == null ) {
+ *              return null;
+ *          }
+ *          HumanDto humanDto = new HumanDto();
+ *          humanDto.setName( human.getName() );
+ *          return humanDto;
+ *      }
+ * }
+ * 
+ * + *

+ * @Mapper
+ * public interface CarMapper {
+ *
+ * @Mapping( target = "seatCount", source = "numberOfSeats")
+ * @Mapping( target = "enginePower", source = "engineClass", ignore=true) // NOTE: source specified as well
+ * CarDto carToDto(Car car);
+ *
+ * @InheritInverseConfiguration
+ * @Mapping(target = "numberOfSeats", ignore = true)
+ * // no need to specify a mapping with ignore for "engineClass": specifying source above will assume
+ * Car carDtoToCar(CarDto carDto);
+ * }
+ * 
+ * @author Sjaak Derksen + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface InheritInverseConfiguration { + + /** + * The name of the inverse mapping method to inherit the mappings from. Needs to be specified only in case more than + * one inverse method exists with a matching source and target type exists. + * + * @return The name of the inverse mapping method to inherit the mappings from. + */ + String name() default ""; +} diff --git a/core/src/main/java/org/mapstruct/InjectionStrategy.java b/core/src/main/java/org/mapstruct/InjectionStrategy.java new file mode 100644 index 0000000000..f5029e2246 --- /dev/null +++ b/core/src/main/java/org/mapstruct/InjectionStrategy.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for handling injection. This is only used on annotated based component models such as CDI, Spring and + * JSR330 / Jakarta. + * + * @author Kevin Grüneberg + * @author Lucas Resch + */ +public enum InjectionStrategy { + + /** Annotations are written on the field **/ + FIELD, + + /** Annotations are written on the constructor **/ + CONSTRUCTOR, + + /** A dedicated setter method is created */ + SETTER +} diff --git a/core/src/main/java/org/mapstruct/IterableMapping.java b/core/src/main/java/org/mapstruct/IterableMapping.java new file mode 100644 index 0000000000..d644dfe03b --- /dev/null +++ b/core/src/main/java/org/mapstruct/IterableMapping.java @@ -0,0 +1,159 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.mapstruct.control.MappingControl; + +/** + * Configures the mapping between two iterable like types, e.g. {@code List} and {@code List}. + * + * + *

Note: either {@link #dateFormat()}, {@link #elementTargetType()} or {@link #qualifiedBy() } + * must be specified

+ * + *

+ * Example: Convert List<Float> to List<String> + *

+ *

+ * @Mapper
+ * public interface FloatToStringMapper {
+ *      @IterableMapping( numberFormat = "##.00" )
+ *      List<String> sourceToTarget(List<Float> source);
+ * }
+ * 
+ *

+ * // generates
+ * public class FloatToStringMapperImpl implements FloatToStringMapper {
+ *      @Override
+ *      public List<String> sourceToTarget(List<Float> source) {
+ *          List<String> list = new ArrayList<String>( source.size() );
+ *          for ( Float float1 : source ) {
+ *              list.add( new DecimalFormat( "##.00" ).format( float1 ) );
+ *          }
+ *     // ...
+ *      }
+ * }
+ * 
+ * + * Supported mappings are: + * + * + * @author Gunnar Morling + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface IterableMapping { + + /** + * A format string as processable by {@link SimpleDateFormat} if the annotated method maps from an iterable of + * {@code String} to an iterable {@link Date} or vice-versa. Will be ignored for all other element types. + *

+ * If the {@link #locale()} is also specified, the format will consider the specified locale when processing + * the date. Otherwise, the system's default locale will be used. + * + * @return A date format string as processable by {@link SimpleDateFormat}. + * @see #locale() + */ + String dateFormat() default ""; + + /** + * A format string as processable by {@link DecimalFormat} if the annotated method maps from a + * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other element types. + *

+ * If the {@link #locale()} is also specified, the number format will be applied in the context of the given locale. + * Otherwise, the system's default locale will be used to process the number format. + * + * @return A decimal format string as processable by {@link DecimalFormat}. + * @see #locale() + */ + String numberFormat() default ""; + + /** + * Specifies the locale to be used when processing {@link #dateFormat()} or {@link #numberFormat()}. + *

+ * The locale should be a plain tag representing the language, such as "en" for English, "de" for German, etc. + *

+ * If no locale is specified, the system's default locale will be used. + * + * @return A string representing the locale to be used when formatting dates or numbers. + */ + String locale() default ""; + + /** + * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple + * mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' error. + * + * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. + * + * @return the qualifiers + * @see Qualifier + */ + Class[] qualifiedBy() default { }; + + /** + * String-based form of qualifiers; When looking for a suitable mapping method to map this iterable mapping method's + * element type, MapStruct will only consider those methods carrying directly or indirectly (i.e. on the + * class-level) a {@link Named} annotation for each of the specified qualifier names. + *

+ * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and + * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large + * number of qualifiers as no custom annotation types are needed. + * + * @return One or more qualifier name(s) + * @see #qualifiedBy() + * @see Named + */ + String[] qualifiedByName() default { }; + + /** + * Specifies the type of the element to be used in the result of the mapping method in case multiple mapping + * methods qualify. + * + * @return the elementTargetType to select + */ + Class elementTargetType() default void.class; + + + /** + * The strategy to be applied when {@code null} is passed as source value to this iterable mapping. If no + * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or + * {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL} + * by default. + * + * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping. + */ + NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class elementMappingControl() default MappingControl.class; + +} diff --git a/core/src/main/java/org/mapstruct/Javadoc.java b/core/src/main/java/org/mapstruct/Javadoc.java new file mode 100644 index 0000000000..4b5d2fb839 --- /dev/null +++ b/core/src/main/java/org/mapstruct/Javadoc.java @@ -0,0 +1,115 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Allows the definition of Javadoc comments in the MapStruct Mapper generated class. + * + *

The annotation provides support for the usual Javadoc comments elements by defining analogous attributes.

+ * + * + *

Please, note that at least one of these attributes must be specified.

+ * + *

+ * For instance, the following definition; + *

+ *

+ * @Javadoc(
+ *     value = "This is the description",
+ *     authors = { "author1", "author2" },
+ *     deprecated = "Use {@link OtherMapper} instead",
+ *     since = "0.1"
+ * )
+ * 
+ * + *

+ * will generate: + *

+ * + *

+ * /**
+ * * This is the description
+ * *
+ * * @author author1
+ * * @author author2
+ * *
+ * * @deprecated Use {@link OtherMapper} instead
+ * * @since 0.1
+ * */
+ * 
+ * + *

+ * The entire Javadoc comment block can be passed directly: + *

+ *

+ * @Javadoc("This is the description\n"
+ *            + "\n"
+ *            + "@author author1\n"
+ *            + "@author author2\n"
+ *            + "\n"
+ *            + "@deprecated Use {@link OtherMapper} instead\n"
+ *            + "@since 0.1\n"
+ * )
+ * 
+ * + *

+ * // or using Text Blocks
+ * @Javadoc(
+ *     """
+ *     This is the description
+ *
+ *     @author author1
+ *     @author author2
+ *
+ *     @deprecated Use {@link OtherMapper} instead
+ *     @since 0.1
+ *     """
+ * )
+ * 
+ */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.SOURCE) +public @interface Javadoc { + /** + * Main Javadoc comment text block. + * + * @return Main Javadoc comment text block. + */ + String value() default ""; + + /** + * List of authors of the code that it is being documented. + *

+ * It will generate a list of the Javadoc tool comment element @author + * with the different values and in the order provided. + * + * @return array of javadoc authors. + */ + String[] authors() default { }; + + /** + * Specifies that the functionality that is being documented is deprecated. + *

+ * Corresponds to the @deprecated Javadoc tool comment element. + * + * @return Deprecation message about the documented functionality + */ + String deprecated() default ""; + + /** + * Specifies the version since the functionality that is being documented is available. + *

+ * Corresponds to the @since Javadoc tool comment element. + * + * @return Version since the functionality is available + */ + String since() default ""; +} diff --git a/core/src/main/java/org/mapstruct/MapMapping.java b/core/src/main/java/org/mapstruct/MapMapping.java new file mode 100644 index 0000000000..093099cf5a --- /dev/null +++ b/core/src/main/java/org/mapstruct/MapMapping.java @@ -0,0 +1,227 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.mapstruct.control.MappingControl; + +/** + * Configures the mapping between two map types, e.g. Map<String, String> and Map<Long, Date>. + * + *

+ * Example: + *

+ *

+ * @Mapper
+ * public interface SimpleMapper {
+ *       @MapMapping(valueDateFormat = "dd.MM.yyyy")
+ *       Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source);
+ * }
+ * 
+ *

+ * // generates
+ * public class SimpleMapperImpl implements SimpleMapper {
+ *      @Override
+ *      public Map<String, String> longDateMapToStringStringMap(Map<Long, Date> source) } {
+ *          Map<String, String> map = new HashMap<String, String>(); }
+ *          for ( java.util.Map.Entry<Long, Date> entry : source.entrySet() ) } {
+ *              String key = new DecimalFormat( "" ).format( entry.getKey() );
+ *              String value = new SimpleDateFormat( "dd.MM.yyyy" ).format( entry.getValue() );
+ *              map.put( key, value );
+ *          }
+ *          // ...
+ *      }
+ * }
+ * 
+ * + *

NOTE: at least one element needs to be specified

+ * + * @author Gunnar Morling + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface MapMapping { + + /** + * A format string as processable by {@link SimpleDateFormat} if the annotated method maps from a map with key type + * {@code String} to an map with key type {@link Date} or vice-versa. Will be ignored for all other key types. + *

+ * If the {@link #locale()} is specified, the format will consider the specified locale when processing the date. + * Otherwise, the system's default locale will be used. + * + * @return A date format string as processable by {@link SimpleDateFormat}. + * @see #locale() + */ + String keyDateFormat() default ""; + + /** + * A format string as processable by {@link SimpleDateFormat} if the annotated method maps from a map with value + * type {@code String} to an map with value type {@link Date} or vice-versa. Will be ignored for all other value + * types. + *

+ * If the {@link #locale()} is specified, the format will consider the specified locale when processing the date. + * Otherwise, the system's default locale will be used. + * + * @return A date format string as processable by {@link SimpleDateFormat}. + * @see #locale() + */ + String valueDateFormat() default ""; + + /** + * A format string as processable by {@link DecimalFormat} if the annotated method maps from a + * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other key types. + *

+ * If the {@link #locale()} is specified, the number format will be applied in the context of the given locale. + * Otherwise, the system's default locale will be used. + * + * @return A decimal format string as processable by {@link DecimalFormat}. + * @see #locale() + */ + String keyNumberFormat() default ""; + + /** + * A format string as processable by {@link DecimalFormat} if the annotated method maps from a + * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other value types. + *

+ * If the {@link #locale()} is specified, the number format will be applied in the context of the given locale. + * Otherwise, the system's default locale will be used. + * + * @return A decimal format string as processable by {@link DecimalFormat}. + * @see #locale() + */ + String valueNumberFormat() default ""; + + /** + * Specifies the locale to be used when processing {@link SimpleDateFormat} or {@link DecimalFormat} for key or + * value mappings in maps. The locale should be a plain tag representing the language, such as "en" for English, + * "de" for German, etc. + *

+ * If no locale is specified, the system's default locale will be used. + * + * @return A string representing the locale to be used when formatting dates or numbers in maps. + */ + String locale() default ""; + + /** + * A key value qualifier can be specified to aid the selection process of a suitable mapper. This is useful in + * case multiple mappers (hand written of internal) qualify and result in an 'Ambiguous mapping methods found' + * error. + * + * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. + * + * @return the qualifiers + * @see Qualifier + */ + Class[] keyQualifiedBy() default { }; + + /** + * String-based form of qualifiers; When looking for a suitable mapping method to map this map mapping method's key + * type, MapStruct will only consider those methods carrying directly or indirectly (i.e. on the class-level) a + * {@link Named} annotation for each of the specified qualifier names. + *

+ * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and + * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large + * number of qualifiers as no custom annotation types are needed. + * + * @return One or more qualifier name(s) + * @see #keyQualifiedBy() + * @see Named + */ + String[] keyQualifiedByName() default { }; + + + /** + * A value qualifier can be specified to aid the selection process of a suitable mapper for the values in the map. + * This is useful in case multiple mappers (hand written of internal) qualify and result in an 'Ambiguous mapping + * methods found' error. + *

+ * A qualifier is a custom annotation and can be placed on either a hand written mapper class or a method. + * + * @return the qualifiers + * @see Qualifier + */ + Class[] valueQualifiedBy() default { }; + + /** + * String-based form of qualifiers; When looking for a suitable mapping method to map this map mapping method's + * value type, MapStruct will only consider those methods carrying directly or indirectly (i.e. on the class-level) + * a {@link Named} annotation for each of the specified qualifier names. + *

+ * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and + * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large + * number of qualifiers as no custom annotation types are needed. + * + * @return One or more qualifier name(s) + * @see #valueQualifiedBy() + * @see Named + */ + String[] valueQualifiedByName() default { }; + + /** + * Specifies the type of the key to be used in the result of the mapping method in case multiple mapping + * methods qualify. + * + * + * @return the resultType to select + */ + Class keyTargetType() default void.class; + + /** + * Specifies the type of the value to be used in the result of the mapping method in case multiple mapping + * methods qualify. + * + * + * @return the resultType to select + */ + Class valueTargetType() default void.class; + + + /** + * The strategy to be applied when {@code null} is passed as source value to this map mapping. If no + * strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} or + * {@link Mapper#nullValueMappingStrategy()} will be applied, using {@link NullValueMappingStrategy#RETURN_NULL} + * by default. + * + * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapping. + */ + NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * Allows detailed control over the key mapping process. + * + * @return the mapping control + * + * @since 1.4 + + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class keyMappingControl() default MappingControl.class; + + + /** + * Allows detailed control over the value mapping process. + * + * @return the mapping control + * + * @since 1.4 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class valueMappingControl() default MappingControl.class; + +} diff --git a/core/src/main/java/org/mapstruct/Mapper.java b/core/src/main/java/org/mapstruct/Mapper.java new file mode 100644 index 0000000000..c502dfe8a9 --- /dev/null +++ b/core/src/main/java/org/mapstruct/Mapper.java @@ -0,0 +1,401 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.control.MappingControl; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.ClassAccessibility.DEFAULT; +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; +import static org.mapstruct.SubclassExhaustiveStrategy.COMPILE_ERROR; + +/** + * Marks an interface or abstract class as a mapper and activates the generation of a implementation of that type via + * MapStruct. + * + *

+ * Example 1: Creating mapper + *

+ *

+ * @Mapper
+ * public interface CarMapper {
+ *     CarDto toCarDto(Car source);
+ * }
+ * 
+ *

+ * Example 2: Use additional mappers with parameters {@link #uses()}, {@link #componentModel()} + * and {@link #injectionStrategy()} + *

+ *

+ * // we have MarkMapper (map field "mark" to field "name" to upper case)
+ * @Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
+ * public class MarkMapper {
+ *     public String mapMark(String mark) {
+ *         return mark.toUpperCase();
+ *     }
+ * }
+ * // we have CarMapper
+ * @Mapper(
+ *      componentModel = MappingConstants.ComponentModel.SPRING,
+ *      uses = MarkMapper.class,
+ *      injectionStrategy = InjectionStrategy.CONSTRUCTOR)
+ * public interface CarMapper {
+ *     @Mapping(target = "name", source = "mark")
+ *     CarDto convertMap(CarEntity carEntity);
+ * }
+ * 
+ *

+ * // generates
+ * @Component
+ * public class CarMapperImpl implements CarMapper {
+ *     private final MarkMapper markMapper;
+ *     @Autowired
+ *     public CarMapperImpl(MarkMapper markMapper) {
+ *         this.markMapper = markMapper;
+ *     }
+ *     @Override
+ *     public CarDto convertMap(CarEntity carEntity) {
+ *         if ( carEntity == null ) {
+ *             return null;
+ *         }
+ *         CarDto carDto = new CarDto();
+ *         carDto.setName( markMapper.mapMark( carEntity.getMark() ) );
+ *         return carDto;
+ *     }
+ * }
+ * 
+ * + * @author Gunnar Morling + * @see Javadoc + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface Mapper { + + /** + * Other mapper types used by this mapper. May be hand-written classes or other mappers generated by MapStruct. No + * cycle between generated mapper classes must be created. + * + * @return The mapper types used by this mapper. + */ + Class[] uses() default { }; + + /** + * Additional types for which an import statement is to be added to the generated mapper implementation class. + * This allows to refer to those types from within mapping expressions given via {@link Mapping#expression()}, + * {@link Mapping#defaultExpression()} or using + * their simple name rather than their fully-qualified name. + * + * @return classes to add in the imports of the generated implementation. + */ + Class[] imports() default { }; + + /** + * How unmapped properties of the source type of a mapping should be + * reported. The method overrides an unmappedSourcePolicy set in a central + * configuration set by {@link #config() } + * + * @return The reporting policy for unmapped source properties. + * + * @since 1.3 + */ + ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE; + + /** + * How unmapped properties of the target type of a mapping should be + * reported. The method overrides an unmappedTargetPolicy set in a central + * configuration set by {@link #config() } + * + * @return The reporting policy for unmapped target properties. + */ + ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN; + + /** + * How lossy (narrowing) conversion, for instance long to integer should be + * reported. The method overrides an typeConversionPolicy set in a central + * configuration set by {@link #config() } + * + * @since 1.3 + * + * @return The reporting policy for unmapped target properties. + */ + ReportingPolicy typeConversionPolicy() default ReportingPolicy.IGNORE; + + /** + * Specifies the component model to which the generated mapper should + * adhere. Supported values are + *
    + *
  • {@code default}: the mapper uses no component model, instances are + * typically retrieved via {@link Mappers#getMapper(Class)}
  • + *
  • + * {@code cdi}: the generated mapper is an application-scoped CDI bean and + * can be retrieved via {@code @Inject}
  • + *
  • + * {@code spring}: the generated mapper is a Spring bean and + * can be retrieved via {@code @Autowired}
  • + *
  • + * {@code jsr330}: the generated mapper is annotated with {@code @javax.inject.Named} and + * {@code @Singleton}, and can be retrieved via {@code @Inject}. + * The annotations will either be from javax.inject or jakarta.inject, + * depending on which one is available, with javax.inject having precedence.
  • + *
  • + * {@code jakarta}: the generated mapper is annotated with {@code @jakarta.inject.Named} and + * {@code @Singleton}, and can be retrieved via {@code @Inject}.
  • + *
+ * The method overrides a componentModel set in a central configuration set + * by {@link #config() } + * + * @return The component model for the generated mapper. + */ + String componentModel() default MappingConstants.ComponentModel.DEFAULT; + + /** + * Specifies the name of the implementation class. The {@code } will be replaced by the + * interface/abstract class name. + *

+ * Defaults to postfixing the name with {@code Impl}: {@code Impl} + * + * @return The implementation name. + * @see #implementationPackage() + */ + String implementationName() default "Impl"; + + /** + * Specifies the target package for the generated implementation. The {@code } will be replaced by the + * interface's or abstract class' package. + *

+ * Defaults to using the same package as the mapper interface/abstract class + * + * @return the implementation package. + * @see #implementationName() + */ + String implementationPackage() default ""; + + /** + * A class annotated with {@link MapperConfig} which should be used as configuration template. Any settings given + * via {@link Mapper} will take precedence over the settings from the referenced configuration source. The list of + * referenced mappers will contain all mappers given via {@link Mapper#uses()} and {@link MapperConfig#uses()}. + * + * @return A class which should be used as configuration template. + */ + Class config() default void.class; + + /** + * The strategy to be applied when propagating the value of collection-typed properties. By default, only JavaBeans + * accessor methods (setters or getters) will be used, but it is also possible to invoke a corresponding adder + * method for each element of the source collection (e.g. {@code orderDto.addOrderLine()}). + *

+ * Any setting given for this attribute will take precedence over {@link MapperConfig#collectionMappingStrategy()}, + * if present. + * + * @return The strategy applied when propagating the value of collection-typed properties. + */ + CollectionMappingStrategy collectionMappingStrategy() default CollectionMappingStrategy.ACCESSOR_ONLY; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to the methods of this mapper. + * If no strategy is configured, the strategy given via {@link MapperConfig#nullValueMappingStrategy()} will be + * applied, using {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @return The strategy to be applied when {@code null} is passed as source value to the methods of this mapper. + */ + NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to an {@link IterableMapping} of + * this mapper. If unset, the strategy set with {@link #nullValueMappingStrategy()} will be applied. If neither + * strategy is configured, the strategy given via {@link MapperConfig#nullValueIterableMappingStrategy()} will be + * applied, using {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.5 + * + * @return The strategy to be applied when {@code null} is passed as source value to an {@link IterableMapping} of + * this mapper. + */ + NullValueMappingStrategy nullValueIterableMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to a {@link MapMapping} of this + * mapper. If unset, the strategy set with {@link #nullValueMappingStrategy()} will be applied. If neither strategy + * is configured, the strategy given via {@link MapperConfig#nullValueMapMappingStrategy()} will be applied, using + * {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.5 + * + * @return The strategy to be applied when {@code null} is passed as source value to a {@link MapMapping} of this + * mapper. + */ + NullValueMappingStrategy nullValueMapMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when a source bean property is {@code null} or not present. If no strategy is + * configured, the strategy given via {@link MapperConfig#nullValuePropertyMappingStrategy()} will be applied, + * {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.3 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() default + NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * The strategy to use for applying method-level configuration annotations of prototype methods in the interface + * specified with {@link #config()}. Annotations that can be inherited are for example {@link Mapping}, + * {@link IterableMapping}, {@link MapMapping}, or {@link BeanMapping}. + *

+ * If no strategy is configured, the strategy given via {@link MapperConfig#mappingInheritanceStrategy()} will be + * applied, using {@link MappingInheritanceStrategy#EXPLICIT} as default. + * + * @return The strategy to use for applying {@code @Mapping} configurations of prototype methods in the interface + * specified with {@link #config()}. + */ + MappingInheritanceStrategy mappingInheritanceStrategy() default MappingInheritanceStrategy.EXPLICIT; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link MapperConfig}, {@link BeanMapping} or {@link Mapping}. + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * Determines how to handle missing implementation for super classes when using the {@link SubclassMapping}. + * + * Can be overridden by the one on {@link BeanMapping}, but overrides {@link MapperConfig}. + * + * @return strategy to handle missing implementation combined with {@link SubclassMappings}. + * + * @since 1.5 + */ + SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR; + + /** + * Specifies the exception type to be thrown when a missing subclass implementation is detected + * in combination with {@link SubclassMappings}, based on the {@link #subclassExhaustiveStrategy()}. + *

+ * This exception will only be thrown when the {@code subclassExhaustiveStrategy} is set to + * {@link SubclassExhaustiveStrategy#RUNTIME_EXCEPTION}. + * + * @return the exception class to throw when missing implementations are found. + * Defaults to {@link IllegalArgumentException}. + */ + Class subclassExhaustiveException() default IllegalArgumentException.class; + + /** + * Determines whether to use field or constructor injection. This is only used on annotated based component models + * such as CDI, Spring and JSR 330. + * + * If no strategy is configured, {@link InjectionStrategy#FIELD} will be used as default. + * + * @return strategy how to inject + */ + InjectionStrategy injectionStrategy() default InjectionStrategy.FIELD; + + /** + * If MapStruct could not find another mapping method or apply an automatic conversion it will try to generate a + * sub-mapping method between the two beans. If this property is set to {@code true} MapStruct will not try to + * automatically generate sub-mapping methods. + *

+ * Can be configured by the {@link MapperConfig#disableSubMappingMethodsGeneration()} as well. + *

+ * Note: If you need to use {@code disableSubMappingMethodsGeneration} please contact the MapStruct team at + * mapstruct.org or + * github.com/mapstruct/mapstruct to share what problem you + * are facing with the automatic sub-mapping generation. + * + * @return whether the automatic generation of sub-mapping methods is disabled + * + * @since 1.2 + */ + boolean disableSubMappingMethodsGeneration() default false; + + /** + * The information that should be used for the builder mappings. This can be used to define custom build methods + * for the builder strategy that one uses. + * + * If no builder is defined the builder given via {@link MapperConfig#builder()} will be applied. + * + *

+ * NOTE: In case no builder is defined here, in {@link BeanMapping} or {@link MapperConfig} and there is a single + * build method, then that method would be used. + *

+ * If the builder is defined and there is a single method that does not match the name of the build method then + * a compile error will occur + * + * @return the builder information + * + * @since 1.3 + */ + Builder builder() default @Builder; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + + /** + * Exception that should be thrown by the generated code if no mapping matches for enums. + * If no exception is configured, the exception given via {@link MapperConfig#unexpectedValueMappingException()} + * will be used, using {@link IllegalArgumentException} by default. + * + *

+ * Note: + *

    + *
  • + * The defined exception should at least have a constructor with a {@link String} parameter. + *
  • + *
  • + * If the defined exception is a checked exception then the enum mapping methods should have that exception + * in the throws clause. + *
  • + *
+ * + * @return the exception that should be used in the generated code + * + * @since 1.4 + */ + Class unexpectedValueMappingException() default IllegalArgumentException.class; + + /** + * Flag indicating whether the addition of a time stamp in the {@code @Generated} annotation should be suppressed. + * i.e. not be added. + * + * The method overrides the flag set in a central configuration set by {@link #config()} + * or through an annotation processor option. + * + * @return whether the addition of a timestamp should be suppressed + * + * @since 1.5 + */ + boolean suppressTimestampInGenerated() default false; + + /** + * Determines the {@link ClassAccessibility} ({@code public} or package-private) for the generated Mapper + * implementation. Default is to mirror the interface or abstract class annotated by this {@code Mapper}. + * + * @return The {@link ClassAccessibility} ({@code public} or package-private) for the generated Mapper + * implementation + */ + ClassAccessibility accessibility() default DEFAULT; +} diff --git a/core/src/main/java/org/mapstruct/MapperConfig.java b/core/src/main/java/org/mapstruct/MapperConfig.java new file mode 100644 index 0000000000..a81e3e8d4f --- /dev/null +++ b/core/src/main/java/org/mapstruct/MapperConfig.java @@ -0,0 +1,371 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.control.MappingControl; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.ClassAccessibility.DEFAULT; +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; +import static org.mapstruct.SubclassExhaustiveStrategy.COMPILE_ERROR; + +/** + * Marks a class or interface as configuration source for generated mappers. This allows to share common configurations + * between several mapper classes. + *

+ * Generally, any settings given via {@link Mapper} take precedence over the settings given via the referenced + * {@code MapperConfig}. The lists of referenced mappers given via {@link Mapper#uses()} and + * {@link MapperConfig#uses()} will be merged. + *

+ * Additionally, mapper configuration classes may declare one more prototype mapping methods. These methods are + * not meant to be invoked themselves (no implementation will generated for mapper config classes), but serve as + * configuration template for mapping methods declared by actual mapper classes. Depending on the configured + * {@link #mappingInheritanceStrategy()}, the configuration can be inherited either explicitly using + * {@link InheritConfiguration} or {@link InheritInverseConfiguration}, or automatically in case all source and target + * types are assignable. + *

+ * + *

+ * Example: + *

+ *

+ * // create config
+ * @MapperConfig(
+ *     uses = CustomMapperViaMapperConfig.class,
+ *     unmappedTargetPolicy = ReportingPolicy.ERROR
+ * )
+ * public interface CentralConfig {
+ * }
+ * 
+ *

+ * // use config
+ * @Mapper(config = CentralConfig.class, uses = { CustomMapperViaMapper.class } )
+ * public interface SourceTargetMapper {
+ *   // ...
+ * }
+ * 
+ *

+ * // result after applying CentralConfig
+ * @Mapper(
+ *     uses = { CustomMapperViaMapper.class, CustomMapperViaMapperConfig.class },
+ *     unmappedTargetPolicy = ReportingPolicy.ERROR
+ * )
+ * public interface SourceTargetMapper {
+ *    // ...
+ * }
+ * 
+ * + * @author Sjaak Derksen + * @see Mapper#config() + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface MapperConfig { + + /** + * The mapper types used by this mapper. + * + * @return The mapper types used by this mapper. + */ + Class[] uses() default { }; + + /** + * Additional types for which an import statement is to be added to the generated mapper implementation class. + * This allows to refer to those types from within mapping expressions given via {@link Mapping#expression()}, + * {@link Mapping#defaultExpression()} or using + * their simple name rather than their fully-qualified name. + * + * @return classes to add in the imports of the generated implementation. + * + * @since 1.4 + */ + Class[] imports() default { }; + + /** + * How unmapped properties of the source type of a mapping should be + * reported. + * + * @return The reporting policy for unmapped source properties. + * + * @since 1.3 + */ + ReportingPolicy unmappedSourcePolicy() default ReportingPolicy.IGNORE; + + /** + * How unmapped properties of the target type of a mapping should be + * reported. + * + * @return The reporting policy for unmapped target properties. + */ + ReportingPolicy unmappedTargetPolicy() default ReportingPolicy.WARN; + + /** + * How lossy (narrowing) conversion, for instance: long to integer should be + * reported. + * + * @since 1.3 + * + * @return The reporting policy for type conversion. + */ + ReportingPolicy typeConversionPolicy() default ReportingPolicy.IGNORE; + + /** + * Specifies the component model to which the generated mapper should + * adhere. Supported values are + *
    + *
  • {@code default}: the mapper uses no component model, instances are + * typically retrieved via {@link Mappers#getMapper(Class)}
  • + *
  • + * {@code cdi}: the generated mapper is an application-scoped CDI bean and + * can be retrieved via {@code @Inject}
  • + *
  • + * {@code spring}: the generated mapper is a Spring bean and + * can be retrieved via {@code @Autowired}
  • + *
  • + * {@code jsr330}: the generated mapper is annotated with {@code @javax.inject.Named} and + * {@code @Singleton}, and can be retrieved via {@code @Inject}. + * The annotations will either be from javax.inject or jakarta.inject, + * depending on which one is available, with javax.inject having precedence.
  • + *
  • + * {@code jakarta}: the generated mapper is annotated with {@code @jakarta.inject.Named} and + * {@code @Singleton}, and can be retrieved via {@code @Inject}.
  • + *
+ * + * @return The component model for the generated mapper. + */ + String componentModel() default MappingConstants.ComponentModel.DEFAULT; + + /** + * Specifies the name of the implementation class. The {@code } will be replaced by the + * interface/abstract class name. + *

+ * Defaults to postfixing the name with {@code Impl}: {@code Impl} + * + * @return The implementation name. + * @see #implementationPackage() + */ + String implementationName() default "Impl"; + + /** + * Specifies the target package for the generated implementation. The {@code } will be replaced by the + * interface's or abstract class' package. + *

+ * Defaults to using the same package as the mapper interface/abstract class + * + * @return the implementation package. + * @see #implementationName() + */ + String implementationPackage() default ""; + + /** + * The strategy to be applied when propagating the value of collection-typed properties. By default, only JavaBeans + * accessor methods (setters or getters) will be used, but it is also possible to invoke a corresponding adder + * method for each element of the source collection (e.g. {@code orderDto.addOrderLine()}). + * + * @return The strategy applied when propagating the value of collection-typed properties. + */ + CollectionMappingStrategy collectionMappingStrategy() default CollectionMappingStrategy.ACCESSOR_ONLY; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to mapping methods. If no + * strategy is configured, {@link NullValueMappingStrategy#RETURN_NULL} will be used by default. + * + * @return The strategy to be applied when {@code null} is passed as source value to mapping methods. + */ + NullValueMappingStrategy nullValueMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to an {@link IterableMapping}. + * If no strategy is configured, the strategy given via {@link #nullValueMappingStrategy()} will be applied, using + * {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.5 + * + * @return The strategy to be applied when {@code null} is passed as source value to an {@link IterableMapping}. + */ + NullValueMappingStrategy nullValueIterableMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when {@code null} is passed as source argument value to a {@link MapMapping}. + * If no strategy is configured, the strategy given via {@link #nullValueMappingStrategy()} will be applied, using + * {@link NullValueMappingStrategy#RETURN_NULL} by default. + * + * @since 1.5 + * + * @return The strategy to be applied when {@code null} is passed as source value to a {@link MapMapping}. + */ + NullValueMappingStrategy nullValueMapMappingStrategy() default NullValueMappingStrategy.RETURN_NULL; + + /** + * The strategy to be applied when a source bean property is {@code null} or not present. If no strategy is + * configured, {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.3 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() default + NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * The strategy to use for applying method-level configuration annotations of prototype methods in the interface + * annotated with this annotation. Annotations that can be inherited are for example {@link Mapping}, + * {@link IterableMapping}, {@link MapMapping}, or {@link BeanMapping}. + *

+ * If no strategy is configured, {@link MappingInheritanceStrategy#EXPLICIT} will be used as default. + * + * @return The strategy to use for applying {@code @Mapping} configurations of prototype methods in the interface + * annotated with this annotation. + */ + MappingInheritanceStrategy mappingInheritanceStrategy() + default MappingInheritanceStrategy.EXPLICIT; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link Mapper}, {@link BeanMapping} or {@link Mapping}. + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * Determines how to handle missing implementation for super classes when using the {@link SubclassMapping}. + * + * Can be overridden by the one on {@link BeanMapping} or {@link Mapper}. + * + * @return strategy to handle missing implementation combined with {@link SubclassMappings}. + * + * @since 1.5 + */ + SubclassExhaustiveStrategy subclassExhaustiveStrategy() default COMPILE_ERROR; + + /** + * Specifies the exception type to be thrown when a missing subclass implementation is detected + * in combination with {@link SubclassMappings}, based on the {@link #subclassExhaustiveStrategy()}. + *

+ * This exception will only be thrown when the {@code subclassExhaustiveStrategy} is set to + * {@link SubclassExhaustiveStrategy#RUNTIME_EXCEPTION}. + * + * @return the exception class to throw when missing implementations are found. + * Defaults to {@link IllegalArgumentException}. + */ + Class subclassExhaustiveException() default IllegalArgumentException.class; + + /** + * Determines whether to use field or constructor injection. This is only used on annotated based component models + * such as CDI, Spring and JSR 330. + * + * Can be overridden by the one on {@link Mapper}. + * + * If no strategy is configured, {@link InjectionStrategy#FIELD} will be used as default. + * + * @return strategy how to inject + */ + InjectionStrategy injectionStrategy() default InjectionStrategy.FIELD; + + /** + * If MapStruct could not find another mapping method or apply an automatic conversion it will try to generate a + * sub-mapping method between the two beans. If this property is set to {@code true} MapStruct will not try to + * automatically generate sub-mapping methods. + *

+ * Can be overridden by {@link Mapper#disableSubMappingMethodsGeneration()} + *

+ * Note: If you need to use {@code disableSubMappingMethodsGeneration} please contact the MapStruct team at + * mapstruct.org or + * github.com/mapstruct/mapstruct to share what problem you + * are facing with the automatic sub-mapping generation. + * + * @return whether the automatic generation of sub-mapping methods is disabled + * + * @since 1.2 + */ + boolean disableSubMappingMethodsGeneration() default false; + + /** + * The information that should be used for the builder mappings. This can be used to define custom build methods + * for the builder strategy that one uses. + * + *

+ * Can be overridden by {@link MapperConfig#builder()}. + * + *

+ * NOTE: In case no builder is defined here, in {@link BeanMapping} or {@link Mapper} and there is a single + * build method, then that method would be used. + *

+ * If the builder is defined and there is a single method that does not match the name of the build method then + * a compile error will occur + * + * @return the builder information + * + * @since 1.3 + */ + Builder builder() default @Builder; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + + /** + * Exception that should be thrown by the generated code if no mapping matches for enums. + * If no exception is configured, {@link IllegalArgumentException} will be used by default. + * + *

+ * Note: + *

    + *
  • + * The defined exception should at least have a constructor with a {@link String} parameter. + *
  • + *
  • + * If the defined exception is a checked exception then the enum mapping methods should have that exception + * in the throws clause. + *
  • + *
+ * + * @return the exception that should be used in the generated code + * + * @since 1.4 + */ + Class unexpectedValueMappingException() default IllegalArgumentException.class; + + /** + * Flag indicating whether the addition of a time stamp in the {@code @Generated} annotation should be suppressed. + * i.e. not be added. + * + * The method overrides the flag set through an annotation processor option. + * + * @return whether the addition of a timestamp should be suppressed + * + * @since 1.5 + */ + boolean suppressTimestampInGenerated() default false; + + /** + * Determines the {@link ClassAccessibility} ({@code public} or package-private) for the generated Mapper + * implementation. Default is to mirror the interface or abstract class annotated by {@code Mapper}. + * + * @return The {@link ClassAccessibility} ({@code public} or package-private) for the generated Mapper + * implementation + */ + ClassAccessibility accessibility() default DEFAULT; +} + diff --git a/core/src/main/java/org/mapstruct/Mapping.java b/core/src/main/java/org/mapstruct/Mapping.java index 86e1810e25..c2a6172e67 100644 --- a/core/src/main/java/org/mapstruct/Mapping.java +++ b/core/src/main/java/org/mapstruct/Mapping.java @@ -1,50 +1,147 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.text.SimpleDateFormat; import java.text.DecimalFormat; +import java.text.SimpleDateFormat; import java.util.Date; +import org.mapstruct.control.MappingControl; + +import static org.mapstruct.NullValueCheckStrategy.ON_IMPLICIT_CONVERSION; + /** - * Configures the mapping of one bean attribute or enum constant. + * Configures the mapping of one bean attribute. *

* The name of the mapped attribute or constant is to be specified via {@link #target()}. For mapped bean attributes it * is assumed by default that the attribute has the same name in the source bean. Alternatively, one of * {@link #source()}, {@link #expression()} or {@link #constant()} can be specified to define the property source. + *

*

* In addition, the attributes {@link #dateFormat()} and {@link #qualifiedBy()} may be used to further define the * mapping. + *

+ * + *

+ * Example 1: Implicitly mapping fields with the same name: + *

+ *

+ * // Both classes HumanDto and Human have property with name "fullName"
+ * // properties with the same name will be mapped implicitly
+ * @Mapper
+ * public interface HumanMapper {
+ *    HumanDto toHumanDto(Human human)
+ * }
+ * 
+ *

+ * // generates:
+ * @Override
+ * public HumanDto toHumanDto(Human human) {
+ *    humanDto.setFullName( human.getFullName() );
+ *    // ...
+ * }
+ * 
* + *

Example 2: Mapping properties with different names

+ *

+ * // We need map Human.companyName to HumanDto.company
+ * // we can use @Mapping with parameters {@link #source()} and {@link #target()}
+ * @Mapper
+ * public interface HumanMapper {
+ *    @Mapping(source="companyName", target="company")
+ *    HumanDto toHumanDto(Human human)
+ * }
+ * 
+ *

+ * // generates:
+ * @Override
+ * public HumanDto toHumanDto(Human human) {
+ *     humanDto.setCompany( human.getCompanyName() );
+ *      // ...
+ * }
+ * 
*

- * IMPORTANT NOTE: the enum mapping capability is deprecated and replaced by {@link ValueMapping} it - * will be removed in subsequent versions. + * Example 3: Mapping with expression + * IMPORTANT NOTE: Now it works only for Java + *

+ *

+ * // We need map Human.name to HumanDto.countNameSymbols.
+ * // we can use {@link #expression()} for it
+ * @Mapper
+ * public interface HumanMapper {
+ *    @Mapping(target="countNameSymbols", expression="java(human.getName().length())")
+ *    HumanDto toHumanDto(Human human)
+ * }
+ * 
+ *

+ * // generates:
+ *@Override
+ * public HumanDto toHumanDto(Human human) {
+ *    humanDto.setCountNameSymbols( human.getName().length() );
+ *    //...
+ * }
+ * 
+ *

+ * Example 4: Mapping to constant + *

+ *

+ * // We need map HumanDto.name to string constant "Unknown"
+ * // we can use {@link #constant()} for it
+ * @Mapper
+ * public interface HumanMapper {
+ *    @Mapping(target="name", constant="Unknown")
+ *    HumanDto toHumanDto(Human human)
+ * }
+ * 
+ *

+ * // generates
+ * @Override
+ * public HumanDto toHumanDto(Human human) {
+ *   humanDto.setName( "Unknown" );
+ *   // ...
+ * }
+ * 
+ *

+ * Example 5: Mapping with default value + *

+ *

+ * // We need map Human.name to HumanDto.fullName, but if Human.name == null, then set value "Somebody"
+ * // we can use {@link #defaultValue()} or {@link #defaultExpression()} for it
+ * @Mapper
+ * public interface HumanMapper {
+ *    @Mapping(source="name", target="fullName", defaultValue="Somebody")
+ *    HumanDto toHumanDto(Human human)
+ * }
+ * 
+ *

+ * // generates
+ * @Override
+ * public HumanDto toHumanDto(Human human) {
+ *    if ( human.getName() != null ) {
+ *       humanDto.setFullName( human.getName() );
+ *    }
+ *    else {
+ *       humanDto.setFullName( "Somebody" );
+ *    }
+ *   // ...
+ * }
+ * 
* * @author Gunnar Morling */ + +@Repeatable(Mappings.class) @Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) +@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface Mapping { /** @@ -78,19 +175,38 @@ /** * A format string as processable by {@link SimpleDateFormat} if the attribute is mapped from {@code String} to * {@link Date} or vice-versa. Will be ignored for all other attribute types and when mapping enum constants. + *

+ * If the {@link #locale()} is also specified, the format will consider the specified locale when processing + * the date. Otherwise, the system's default locale will be used. * * @return A date format string as processable by {@link SimpleDateFormat}. + * @see #locale() */ String dateFormat() default ""; /** * A format string as processable by {@link DecimalFormat} if the annotated method maps from a * {@link Number} to a {@link String} or vice-versa. Will be ignored for all other element types. + *

+ * If the {@link #locale()} is also specified, the number format will be applied in the context of the given locale. + * Otherwise, the system's default locale will be used to process the number format. * * @return A decimal format string as processable by {@link DecimalFormat}. + * @see #locale() */ String numberFormat() default ""; + /** + * Specifies the locale to be used when processing {@link #dateFormat()} or {@link #numberFormat()}. + *

+ * The locale should be a plain tag representing the language, such as "en" for English, "de" for German, etc. + *

+ * If no locale is specified, the system's default locale will be used. + * + * @return A string representing the locale to be used when formatting dates or numbers. + */ + String locale() default ""; + /** * A constant {@link String} based on which the specified target property is to be set. *

@@ -109,18 +225,18 @@ * If not possible, MapStruct will try to apply a user defined mapping method. * * - *

- * Please note that grouping underscores and binary literals are not supported in Java 6 - *

* *
  • other *

    * MapStruct handles the constant as {@code String}. The value will be converted by applying a matching method, * type conversion method or built-in conversion. - *

    *

  • * *

    + * You can use {@link #qualifiedBy()} or {@link #qualifiedByName()} to force the use of a conversion method + * even when one would not apply. (e.g. {@code String} to {@code String}) + *

    + *

    * This attribute can not be used together with {@link #source()}, {@link #defaultValue()}, * {@link #defaultExpression()} or {@link #expression()}. * @@ -148,7 +264,7 @@ * imported via {@link Mapper#imports()}. *

    * This attribute can not be used together with {@link #source()}, {@link #defaultValue()}, - * {@link #defaultExpression()} or {@link #constant()}. + * {@link #defaultExpression()}, {@link #qualifiedBy()}, {@link #qualifiedByName()} or {@link #constant()}. * * @return An expression specifying the value for the designated target property */ @@ -186,9 +302,12 @@ /** * Whether the property specified via {@link #target()} should be ignored by the generated mapping method or not. - * This can be useful when certain attributes should not be propagated from source or target or when properties in + * This can be useful when certain attributes should not be propagated from source to target or when properties in * the target object are populated using a decorator and thus would be reported as unmapped target property by * default. + *

    + * If you have multiple properties to ignore, + * you can use the {@link Ignored} annotation instead and group them all at once. * * @return {@code true} if the given property should be ignored, {@code false} otherwise */ @@ -198,8 +317,11 @@ * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple * mapping methods (hand written or generated) qualify and thus would result in an 'Ambiguous mapping methods found' * error. A qualifier is a custom annotation and can be placed on a hand written mapper class or a method. + *

    + * Note that {@link #defaultValue()} usage will also be converted using this qualifier. * * @return the qualifiers + * @see Qualifier */ Class[] qualifiedBy() default { }; @@ -211,6 +333,8 @@ * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large * number of qualifiers as no custom annotation types are needed. + *

    + * Note that {@link #defaultValue()} usage will also be converted using this qualifier. * * @return One or more qualifier name(s) * @see #qualifiedBy() @@ -218,6 +342,72 @@ */ String[] qualifiedByName() default { }; + /** + * A qualifier can be specified to aid the selection process of a suitable presence check method. + * This is useful in case multiple presence check methods qualify and thus would result in an + * 'Ambiguous presence check methods found' error. + * A qualifier is a custom annotation and can be placed on a hand written mapper class or a method. + * This is similar to the {@link #qualifiedBy()}, but it is only applied for {@link Condition} methods. + * + * @return the qualifiers + * @see Qualifier + * @see #qualifiedBy() + * @since 1.5 + */ + Class[] conditionQualifiedBy() default { }; + + /** + * String-based form of qualifiers for condition / presence check methods; + * When looking for a suitable presence check method for a given property, MapStruct will + * only consider those methods carrying directly or indirectly (i.e. on the class-level) a {@link Named} annotation + * for each of the specified qualifier names. + * + * This is similar like {@link #qualifiedByName()} but it is only applied for {@link Condition} methods. + *

    + * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and + * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large + * number of qualifiers as no custom annotation types are needed. + *

    + * + * + * @return One or more qualifier name(s) + * @see #conditionQualifiedBy() + * @see #qualifiedByName() + * @see Named + * @since 1.5 + */ + String[] conditionQualifiedByName() default { }; + + /** + * A conditionExpression {@link String} based on which the specified property is to be checked + * whether it is present or not. + *

    + * Currently, Java is the only supported "expression language" and expressions must be given in form of Java + * expressions using the following format: {@code java()}. For instance the mapping: + *

    
    +     * @Mapping(
    +     *     target = "someProp",
    +     *     conditionExpression = "java(s.getAge() < 18)"
    +     * )
    +     * 
    + *

    + * will cause the following target property assignment to be generated: + *

    
    +     *     if (s.getAge() < 18) {
    +     *         targetBean.setSomeProp( s.getSomeProp() );
    +     *     }
    +     * 
    + *

    + * Any types referenced in expressions must be given via their fully-qualified name. Alternatively, types can be + * imported via {@link Mapper#imports()}. + *

    + * This attribute can not be used together with {@link #expression()} or {@link #constant()}. + * + * @return An expression specifying a condition check for the designated property + * + * @since 1.5 + */ + String conditionExpression() default ""; /** * Specifies the result type of the mapping method to be used in case multiple mapping methods qualify. @@ -255,15 +445,11 @@ * If not possible, MapStruct will try to apply a user defined mapping method. * * - *

    - * Please note that grouping underscores and binary literals are not supported in Java 6 - *

    * *
  • other *

    * MapStruct handles the constant as {@code String}. The value will be converted by applying a matching method, * type conversion method or built-in conversion. - *

    *

  • * *

    @@ -273,4 +459,45 @@ * @return Default value to set in case the source property is {@code null}. */ String defaultValue() default ""; + + /** + * Determines when to include a null check on the source property value of a bean mapping. + * + * Can be overridden by the one on {@link MapperConfig}, {@link Mapper} or {@link BeanMapping}. + * + * @since 1.3 + * + * @return strategy how to do null checking + */ + NullValueCheckStrategy nullValueCheckStrategy() default ON_IMPLICIT_CONVERSION; + + /** + * The strategy to be applied when the source property is {@code null} or not present. If no strategy is configured, + * the strategy given via {@link MapperConfig#nullValuePropertyMappingStrategy()}, + * {@link BeanMapping#nullValuePropertyMappingStrategy()} or + * {@link Mapper#nullValuePropertyMappingStrategy()} will be applied. + * + * {@link NullValuePropertyMappingStrategy#SET_TO_NULL} will be used by default. + * + * @since 1.3 + * + * @return The strategy to be applied when {@code null} is passed as source property value or the source property + * is not present. + */ + NullValuePropertyMappingStrategy nullValuePropertyMappingStrategy() + default NullValuePropertyMappingStrategy.SET_TO_NULL; + + /** + * Allows detailed control over the mapping process. + * + * @return the mapping control + * + * @since 1.4 + * + * @see org.mapstruct.control.DeepClone + * @see org.mapstruct.control.NoComplexMapping + * @see org.mapstruct.control.MappingControl + */ + Class mappingControl() default MappingControl.class; + } diff --git a/core/src/main/java/org/mapstruct/MappingConstants.java b/core/src/main/java/org/mapstruct/MappingConstants.java new file mode 100644 index 0000000000..3d3d8a4c77 --- /dev/null +++ b/core/src/main/java/org/mapstruct/MappingConstants.java @@ -0,0 +1,154 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Contains all constants defined in the mapping process. + * + * @author Sjaak Derksen + */ +public final class MappingConstants { + + private MappingConstants() { + } + + /** + * In an {@link ValueMapping} this represents a {@code null} source or target. + */ + public static final String NULL = ""; + + /** + * In an {@link ValueMapping} this represents any source that is not already mapped by either a defined mapping or + * by means of name based mapping. + * + * NOTE: The value is only applicable to {@link ValueMapping#source()} and not to {@link ValueMapping#target()}. + */ + public static final String ANY_REMAINING = ""; + + /** + * In an {@link ValueMapping} this represents any source that is not already mapped by a defined mapping. + * + * NOTE: The value is only applicable to {@link ValueMapping#source()} and not to {@link ValueMapping#target()}. + * + */ + public static final String ANY_UNMAPPED = ""; + + /** + * In an {@link ValueMapping} this represents any target that will be mapped to an + * {@link java.lang.IllegalArgumentException} which will be thrown at runtime. + *

    + * NOTE: The value is only applicable to {@link ValueMapping#target()} and not to {@link ValueMapping#source()}. + */ + public static final String THROW_EXCEPTION = ""; + + /** + * In an {@link EnumMapping} this represent the enum transformation strategy that adds a suffix to the source enum. + * + * @since 1.4 + */ + public static final String SUFFIX_TRANSFORMATION = "suffix"; + + /** + * In an {@link EnumMapping} this represent the enum transformation strategy that strips a suffix from the source + * enum. + * + * @since 1.4 + */ + public static final String STRIP_SUFFIX_TRANSFORMATION = "stripSuffix"; + + /** + * In an {@link EnumMapping} this represent the enum transformation strategy that adds a prefix to the source enum. + * + * @since 1.4 + */ + public static final String PREFIX_TRANSFORMATION = "prefix"; + + /** + * In an {@link EnumMapping} this represent the enum transformation strategy that strips a prefix from the source + * enum. + * + * @since 1.4 + */ + public static final String STRIP_PREFIX_TRANSFORMATION = "stripPrefix"; + + /** + * In an {@link EnumMapping} this represent the enum transformation strategy that applies case transformation + * at the source. + * + * @since 1.5 + */ + public static final String CASE_TRANSFORMATION = "case"; + + /** + * Specifies the component model constants to which the generated mapper should adhere. + * It can be used with the annotation {@link Mapper#componentModel()} or {@link MapperConfig#componentModel()} + * + *

    + * Example: + *

    + *
    
    +    * // Spring component model
    +    * @Mapper(componentModel = MappingConstants.ComponentModel.SPRING)
    +    * 
    + * + * @since 1.5.0 + */ + public static final class ComponentModel { + + private ComponentModel() { + } + + /** + * The mapper uses no component model, instances are typically retrieved + * via {@link org.mapstruct.factory.Mappers#getMapper(java.lang.Class)} + * + */ + public static final String DEFAULT = "default"; + + /** + * The generated mapper is an application-scoped CDI bean and can be retrieved via @Inject. + * The annotations are either from {@code javax} or {@code jakarta}. + * Priority have the {@code javax} annotations. + * In case you want to only use Jakarta then use {@link #JAKARTA_CDI}. + * + * @see #JAKARTA_CDI + */ + public static final String CDI = "cdi"; + + /** + * The generated mapper is a Spring bean and can be retrieved via @Autowired + * + */ + public static final String SPRING = "spring"; + + /** + * The generated mapper is annotated with @Named and @Singleton, and can be retrieved via @Inject. + * The annotations are either from {@code javax.inject} or {@code jakarta.inject}. + * Priority have the {@code javax.inject} annotations. + * In case you want to only use Jakarta then use {@link #JAKARTA}. + * + * @see #JAKARTA + */ + public static final String JSR330 = "jsr330"; + + /** + * The generated mapper is annotated with @Named and @Singleton, and can be retrieved via @Inject. + * The annotations are from {@code jakarta.inject}. + * In case you want to use {@code javax.inject} then use {@link #JSR330}. + * + * @see #JSR330 + */ + public static final String JAKARTA = "jakarta"; + + /** + * The generated mapper is an application-scoped Jakarta CDI bean and can be retrieved via @Inject. + * @see #CDI + */ + public static final String JAKARTA_CDI = "jakarta-cdi"; + + } + +} diff --git a/core/src/main/java/org/mapstruct/MappingInheritanceStrategy.java b/core/src/main/java/org/mapstruct/MappingInheritanceStrategy.java new file mode 100644 index 0000000000..ff57b45841 --- /dev/null +++ b/core/src/main/java/org/mapstruct/MappingInheritanceStrategy.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for inheriting configurations given for methods of prototype mapping methods (declared on mapper config + * classes) to actual mapping methods declared on mappers referring to such config class via {@link Mapper#config()}. + * + * @author Andreas Gudian + */ +public enum MappingInheritanceStrategy { + /** + * Apply the method-level configuration annotations only if the prototype method is explicitly referenced using + * {@link InheritConfiguration}. + */ + EXPLICIT, + + /** + * Inherit the method-level forward configuration annotations automatically if source and target types of the + * prototype method are assignable from the types of a given mapping method. + */ + AUTO_INHERIT_FROM_CONFIG, + + /** + * Inherit the method-level reverse configuration annotations automatically if source and target types of the + * prototype method are assignable from the target and source types of a given mapping method. + */ + AUTO_INHERIT_REVERSE_FROM_CONFIG, + + /** + * Inherit the method-level forward and reverse configuration annotations automatically if source and target types + * of the prototype method are assignable from the types of a given mapping method. + */ + AUTO_INHERIT_ALL_FROM_CONFIG; +} diff --git a/core/src/main/java/org/mapstruct/MappingTarget.java b/core/src/main/java/org/mapstruct/MappingTarget.java new file mode 100644 index 0000000000..3916448368 --- /dev/null +++ b/core/src/main/java/org/mapstruct/MappingTarget.java @@ -0,0 +1,62 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Declares a parameter of a mapping method to be the target of the mapping. + *

    + * Not more than one parameter can be declared as {@code MappingTarget}. + *

    + * NOTE: The parameter passed as a mapping target must not be {@code null}. + * + *

    + * Example 1: Update exist bean without return value + *

    + *
    
    + * @Mapper
    + * public interface HumanMapper {
    + *     void updateHuman(HumanDto humanDto, @MappingTarget Human human);
    + * }
    + * 
    + *
    
    + * // generates
    + * @Override
    + * public void updateHuman(HumanDto humanDto, Human human) {
    + *     human.setName( humanDto.getName() );
    + *     // ...
    + * }
    + * 
    + *

    + * Example 2: Update exist bean and return it + *

    + *
    
    + * @Mapper
    + * public interface HumanMapper {
    + *     Human updateHuman(HumanDto humanDto, @MappingTarget Human human);
    + * }
    + * 
    + * // generates: + *
    
    + * @Override
    + * public Human updateHuman(HumanDto humanDto, Human human) {
    + *     // ...
    + *     human.setName( humanDto.getName() );
    + *     return human;
    + * }
    + *
    + * + * + * @author Andreas Gudian + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.CLASS) +public @interface MappingTarget { +} diff --git a/core/src/main/java/org/mapstruct/Mappings.java b/core/src/main/java/org/mapstruct/Mappings.java index 9bc3b1f7fa..1578a648a9 100644 --- a/core/src/main/java/org/mapstruct/Mappings.java +++ b/core/src/main/java/org/mapstruct/Mappings.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; @@ -25,11 +12,37 @@ /** * Configures the mappings of several bean attributes. + *

    + * TIP: When using Java 8 or later, you can omit the @Mappings + * wrapper annotation and directly specify several @Mapping annotations on one method. + * + *

    These two examples are equal. + *

    + *
    
    + * // before Java 8
    + * @Mapper
    + * public interface MyMapper {
    + *     @Mappings({
    + *         @Mapping(target = "firstProperty", source = "first"),
    + *         @Mapping(target = "secondProperty", source = "second")
    + *     })
    + *     HumanDto toHumanDto(Human human);
    + * }
    + * 
    + *
    
    + * // Java 8 and later
    + * @Mapper
    + * public interface MyMapper {
    + *     @Mapping(target = "firstProperty", source = "first"),
    + *     @Mapping(target = "secondProperty", source = "second")
    + *     HumanDto toHumanDto(Human human);
    + * }
    + * 
    * * @author Gunnar Morling */ @Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface Mappings { /** diff --git a/core/src/main/java/org/mapstruct/Named.java b/core/src/main/java/org/mapstruct/Named.java new file mode 100644 index 0000000000..773886a7b1 --- /dev/null +++ b/core/src/main/java/org/mapstruct/Named.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Marks mapping methods with the given qualifier name. Can be used to qualify a single method or all methods of a given + * type by specifying this annotation on the type level. + *

    + * Will be used to select the correct mapping methods when mapping a bean property type, element of an iterable type + * or the key/value of a map type. + *

    + * Example (both methods of {@code Titles} are capable to convert a string, but the ambiguity is resolved by applying + * the qualifiers in {@code @Mapping}: + * + *

    + * 
    + * @Named("TitleTranslator")
    + * public class Titles {
    + *
    + *   @Named("EnglishToGerman")
    + *   public String translateTitleEG(String title) {
    + *       // some mapping logic
    + *   }
    + *
    + *   @Named("GermanToEnglish")
    + *   public String translateTitleGE(String title) {
    + *       // some mapping logic
    + *   }
    + * }
    + *
    + * @Mapper( uses = Titles.class )
    + * public interface MovieMapper {
    + *
    + *    @Mapping( target = "title", qualifiedByName = { "TitleTranslator", "EnglishToGerman" } )
    + *    GermanRelease toGerman( OriginalRelease movies );
    + *
    + * }
    + * 
    + * 
    + * + * The following implementation of {@code MovieMapper} will be generated: + * + *
    + * 
    + *
    + * public class MovieMapperImpl implements MovieMapper {
    + *     private final Titles titles = new Titles();
    + *
    + *     @Override
    + *     public GermanRelease toGerman(OriginalRelease movies) {
    + *         if ( movies == null ) {
    + *             return null;
    + *         }
    + *
    + *         GermanRelease germanRelease = new GermanRelease();
    + *
    + *         germanRelease.setTitle( titles.translateTitleEG( movies.getTitle() ) );
    + *
    + *         return germanRelease;
    + *     }
    + * }
    + * 
    + * 
    + * + * @author Sjaak Derksen + * @see org.mapstruct.Mapping#qualifiedByName() + * @see IterableMapping#qualifiedByName() + * @see MapMapping#keyQualifiedByName() + * @see MapMapping#valueQualifiedByName() + */ +@Target( { ElementType.TYPE, ElementType.METHOD } ) +@Retention( RetentionPolicy.CLASS ) +@Qualifier +public @interface Named { + + /** + * A name qualifying the annotated element + * + * @return the name. + */ + String value(); +} diff --git a/core/src/main/java/org/mapstruct/NullEnum.java b/core/src/main/java/org/mapstruct/NullEnum.java new file mode 100644 index 0000000000..ac39b3485d --- /dev/null +++ b/core/src/main/java/org/mapstruct/NullEnum.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * To be used as a default value for enum class annotation elements. + * + * @author Ben Zegveld + * @since 1.6 + */ +enum NullEnum { +} diff --git a/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java b/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java new file mode 100644 index 0000000000..22dba7c58b --- /dev/null +++ b/core/src/main/java/org/mapstruct/NullValueCheckStrategy.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for dealing with null source values. + * + * Note: This strategy is not in effect when a specific source presence check method is defined + * in the service provider interface (SPI). + *

    + * Note: some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder + * as target accessor see {@link CollectionMappingStrategy}, MapStruct will always generate a source property null + * check, regardless the value of the {@link NullValueCheckStrategy} to avoid addition of {@code null} to the target + * collection or map. + * + * @author Sean Huang + */ +public enum NullValueCheckStrategy { + + /** + * This option includes a null check. When: + *
    + *
    + *

      + *
    1. a source value is directly assigned to a target
    2. + *
    3. a source value assigned to a target by calling a type conversion on the target first
    4. + *
    + *
    + * NOTE: mapping methods (generated or hand written) are excluded from this null check. They are intended to + * handle a null source value as 'valid' input. + * + */ + ON_IMPLICIT_CONVERSION, + + /** + * This option always includes a null check. + */ + ALWAYS; + +} diff --git a/core/src/main/java/org/mapstruct/NullValueMappingStrategy.java b/core/src/main/java/org/mapstruct/NullValueMappingStrategy.java new file mode 100644 index 0000000000..4cece83031 --- /dev/null +++ b/core/src/main/java/org/mapstruct/NullValueMappingStrategy.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for dealing with {@code null} values passed to mapping methods. + * + * @author Sjaak Derksen + */ +public enum NullValueMappingStrategy { + + /** + * If {@code null} is passed to a mapping method, {@code null} will be returned, unless the return type is + * {@link java.util.Optional Optional}, in which case an empty optional will be returned. + * That's the default behavior if no alternative strategy is configured globally, for given mapper or method. + */ + RETURN_NULL, + + /** + * If {@code null} is passed to a mapping method, a default value will be returned. The value depends on the kind of + * the annotated method: + *
      + *
    • For bean mapping methods the target type will be instantiated and returned. Any properties of the target type + * which are mapped via {@link Mapping#expression()} or {@link Mapping#constant()} will be populated based on the + * given expression or constant. Note that expressions must be prepared to deal with {@code null} values in this + * case.
    • + *
    • For iterable mapping methods an empty collection will be returned.
    • + *
    • For map mapping methods an empty map will be returned.
    • + *
    • For optional mapping methods an empty optional will be returned.
    • + *
    + */ + RETURN_DEFAULT; +} diff --git a/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java b/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java new file mode 100644 index 0000000000..0ab30d5271 --- /dev/null +++ b/core/src/main/java/org/mapstruct/NullValuePropertyMappingStrategy.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for dealing with {@code null} or not present properties in the source bean. The + * {@link NullValuePropertyMappingStrategy} can be defined on {@link MapperConfig}, {@link Mapper}, {@link BeanMapping} + * and {@link Mapping}. + * Precedence is arranged in the reverse order. So {@link Mapping} will override {@link BeanMapping}, will + * override {@link Mapper} + * + * The enum only applies to update methods: methods that update a pre-existing target (annotated with + * {@code @}{@link MappingTarget}). + * + *

    + * Note: some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder + * as target accessor see {@link CollectionMappingStrategy}, MapStruct will always generate a source property + * null check, regardless the value of the {@link NullValuePropertyMappingStrategy} to avoid addition of {@code null} + * to the target collection or map. Since the target is assumed to be initialised this strategy will not be applied. + * + * @author Sjaak Derksen + * @since 1.3 + */ +public enum NullValuePropertyMappingStrategy { + + /** + * If a source bean property equals {@code null} the target bean property will be set explicitly to {@code null} + * or {@link java.util.Optional#empty() Optional.empty()} in case the target type is an + * {@link java.util.Optional Optional}. + */ + SET_TO_NULL, + + /** + * If a source bean property equals {@code null} the target bean property will be set to its default value. + *

    + * This means: + *

      + *
    1. For {@code Optional} MapStruct generates an {@code Optional.empty()}
    2. + *
    3. For {@code List} MapStruct generates an {@code ArrayList}
    4. + *
    5. For {@code Map} a {@code HashMap}
    6. + *
    7. For arrays an empty array
    8. + *
    9. For {@code String} {@code ""}
    10. + *
    11. for primitive / boxed types a representation of {@code 0} or {@code false}
    12. + *
    13. For all other objects an new instance is created, requiring an empty constructor.
    14. + *
    + *

    + * Make sure that a {@link Mapping#defaultValue()} is defined if no empty constructor is available on + * the default value. + */ + SET_TO_DEFAULT, + + /** + * If a source bean property equals {@code null} the target bean property will be ignored and retain its + * existing value. + */ + IGNORE, + + /** + * If a source bean property equals {@code null} the target bean property will be cleared. + * This strategy is only applicable to target properties that are of type {@link java.util.Collection Collection} + * or {@link java.util.Map Map}. + */ + CLEAR; +} diff --git a/core/src/main/java/org/mapstruct/ObjectFactory.java b/core/src/main/java/org/mapstruct/ObjectFactory.java new file mode 100644 index 0000000000..dc0e92de8d --- /dev/null +++ b/core/src/main/java/org/mapstruct/ObjectFactory.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks a method as a factory method to create beans. + *

    + * By default beans are created during the mapping process with the default constructor. If a factory method with a + * return type that is assignable to the required object type is present, then the factory method is used instead. + *

    + * Factory methods can be defined without parameters, with an {@code @}{@link TargetType} parameter, a + * {@code @}{@link Context} parameter, or with the mapping source parameter. If any of those parameters are defined, + * then the mapping method that is supposed to use the factory method needs to be declared with an assignable result + * type, assignable context parameter, and/or assignable source types. + *

    + * Note: the usage of this annotation is optional when used in the {@link Mapper#uses()} + * if no source parameters are part of the signature, i.e. it is declared without parameters or only with + * {@code @}{@link TargetType} and/or {@code @}{@link Context}. It is however mandatory when used inside + * an {@code @}{@link Context} annotated class. + *

    + * Example: Using a factory method for entities to check whether the entity already exists in the + * EntityManager and then returns the managed instance: + * + *

    + * 
    + * @ApplicationScoped // CDI component model
    + * public class ReferenceMapper {
    + *
    + *     @PersistenceContext
    + *     private EntityManager em;
    + *
    + *     @ObjectFactory
    + *     public <T extends AbstractEntity> T resolve(AbstractDto sourceDto, @TargetType Class<T> type) {
    + *         T entity = em.find( type, sourceDto.getId() );
    + *         return entity != null ? entity : type.newInstance();
    + *     }
    + * }
    + * 
    + * 
    + *

    + * If there are two factory methods, both serving the same type, one with no parameters and one taking sources as input, + * then the one with the source parameters is favored. If there are multiple such factories, an ambiguity error is + * shown. + * + * @author Remo Meier + * @since 1.2 + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.METHOD) +public @interface ObjectFactory { + +} diff --git a/core/src/main/java/org/mapstruct/Qualifier.java b/core/src/main/java/org/mapstruct/Qualifier.java new file mode 100644 index 0000000000..9e18c3e420 --- /dev/null +++ b/core/src/main/java/org/mapstruct/Qualifier.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Declares an annotation type to be a qualifier. Qualifier annotations allow unambiguously identify a suitable mapping + * method in case several methods qualify to map a bean property, iterable element etc. + *

    + * Can be used in: + *

      + *
    • {@link Mapping#qualifiedBy() }
    • + *
    • {@link BeanMapping#qualifiedBy() }
    • + *
    • {@link IterableMapping#qualifiedBy() }
    • + *
    • {@link MapMapping#keyQualifiedBy() }
    • + *
    • {@link MapMapping#valueQualifiedBy() }
    • + *
    • {@link SubclassMapping#qualifiedBy() }
    • + *
    + *

    Example:

    + *
    
    + * // create qualifiers
    + * @Qualifier
    + * @Target(ElementType.TYPE)
    + * @Retention(RetentionPolicy.CLASS)
    + * public @interface TitleTranslator {}
    + *
    + * @Qualifier
    + * @Target(ElementType.METHOD)
    + * @Retention(RetentionPolicy.CLASS)
    + * public @interface EnglishToGerman {}
    + *
    + * @Qualifier
    + * @Target(ElementType.METHOD)
    + * @Retention(RetentionPolicy.CLASS)
    + * public @interface GermanToEnglish {}
    + * 
    + *
    
    + * // we can create class with map methods
    + * @TitleTranslator
    + * public class Titles {
    + *     @EnglishToGerman
    + *     public String translateTitleEnglishToGerman(String title) {
    + *         // some mapping logic
    + *     }
    + *     @GermanToEnglish
    + *     public String translateTitleGermanToEnglish(String title) {
    + *         // some mapping logic
    + *     }
    + * }
    + * 
    + *
    
    + * // usage
    + * @Mapper( uses = Titles.class )
    + * public interface MovieMapper {
    + *      @Mapping( target = "title", qualifiedBy = { TitleTranslator.class, EnglishToGerman.class } )
    + *      GermanRelease toGerman( OriginalRelease movies );
    + * }
    + * 
    + *
    
    + * // generates
    + * public class MovieMapperImpl implements MovieMapper {
    + *      private final Titles titles = new Titles();
    + *      @Override
    + *      public GermanRelease toGerman(OriginalRelease movies) {
    + *          if ( movies == null ) {
    + *              return null;
    + *          }
    + *          GermanRelease germanRelease = new GermanRelease();
    + *          germanRelease.setTitle( titles.translateTitleEnglishToGerman( movies.getTitle() ) );
    + *          return germanRelease;
    + *     }
    + * }
    + * 
    + * + * NOTE: Qualifiers should have {@link RetentionPolicy#CLASS}. + * + * @author Sjaak Derksen + * @see Named + */ +@Target(ElementType.ANNOTATION_TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface Qualifier { +} diff --git a/core/src/main/java/org/mapstruct/ReportingPolicy.java b/core/src/main/java/org/mapstruct/ReportingPolicy.java new file mode 100644 index 0000000000..78b510aac7 --- /dev/null +++ b/core/src/main/java/org/mapstruct/ReportingPolicy.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import javax.tools.Diagnostic.Kind; + +/** + * Policy for reporting issues occurring during the generation of a mapper + * implementation. + * + * @author Gunnar Morling + */ +public enum ReportingPolicy { + + /** + * No report will be created for the given issue. + */ + IGNORE, + + /** + * A report with {@link Kind#WARNING} will be created for the given issue. + */ + WARN, + + /** + * A report with {@link Kind#ERROR} will be created for the given issue, + * causing the compilation to fail. + */ + ERROR; +} diff --git a/core/src/main/java/org/mapstruct/SourceParameterCondition.java b/core/src/main/java/org/mapstruct/SourceParameterCondition.java new file mode 100644 index 0000000000..8bff97abc4 --- /dev/null +++ b/core/src/main/java/org/mapstruct/SourceParameterCondition.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks a method as a check method to check if a source parameter needs to be mapped. + *

    + * By default, source parameters are checked against {@code null}, unless they are primitives. + *

    + * Check methods have to return {@code boolean}. + * The following parameters are accepted for the presence check methods: + *

      + *
    • The mapping source parameter
    • + *
    • {@code @}{@link Context} parameter
    • + *
    + * + * Note: The usage of this annotation is mandatory + * for a method to be considered as a source check method. + * + *
    
    + * public class PresenceCheckUtils {
    + *
    + *   @SourceParameterCondition
    + *   public static boolean isDefined(Car car) {
    + *      return car != null && car.getId() != null;
    + *   }
    + * }
    + *
    + * @Mapper(uses = PresenceCheckUtils.class)
    + * public interface CarMapper {
    + *
    + *     CarDto map(Car car);
    + * }
    + * 
    + * + * The following implementation of {@code CarMapper} will be generated: + * + *
    
    + * public class CarMapperImpl implements CarMapper {
    + *
    + *     @Override
    + *     public CarDto map(Car car) {
    + *         if ( !PresenceCheckUtils.isDefined( car ) ) {
    + *             return null;
    + *         }
    + *
    + *         CarDto carDto = new CarDto();
    + *
    + *         carDto.setId( car.getId() );
    + *         // ...
    + *
    + *         return carDto;
    + *     }
    + * }
    + * 
    + * + * @author Filip Hrisafov + * @since 1.6 + * @see Condition @Condition + */ +@Target({ ElementType.METHOD }) +@Retention(RetentionPolicy.CLASS) +@Condition(appliesTo = ConditionStrategy.SOURCE_PARAMETERS) +public @interface SourceParameterCondition { + +} diff --git a/core/src/main/java/org/mapstruct/SourcePropertyName.java b/core/src/main/java/org/mapstruct/SourcePropertyName.java new file mode 100644 index 0000000000..a9d036d5d8 --- /dev/null +++ b/core/src/main/java/org/mapstruct/SourcePropertyName.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks a presence check method parameter as a source property name parameter. + *

    + * This parameter enables conditional filtering based on source property name at run-time. + * Parameter must be of type {@link String} and can be present only in {@link Condition} method. + *

    + * + * @author Oliver Erhart + * @since 1.6 + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.CLASS) +public @interface SourcePropertyName { +} diff --git a/core/src/main/java/org/mapstruct/SubclassExhaustiveStrategy.java b/core/src/main/java/org/mapstruct/SubclassExhaustiveStrategy.java new file mode 100644 index 0000000000..a60d067faa --- /dev/null +++ b/core/src/main/java/org/mapstruct/SubclassExhaustiveStrategy.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +/** + * Strategy for dealing with subclassMapping annotated methods. + * + * @since 1.5 + * @author Ben Zegveld + */ +public enum SubclassExhaustiveStrategy { + + /** + * If there is no valid constructor or known method to create the return value of a with `@SubclassMapping` + * annotated mapping then a compilation error will be thrown. + */ + COMPILE_ERROR, + + /** + * If there is no valid constructor or known method to create the return value of a with `@SubclassMapping` + * annotated mapping then an {@link IllegalArgumentException} will be thrown if a call is made with a type for which + * there is no {@link SubclassMapping} available. + */ + RUNTIME_EXCEPTION; +} diff --git a/core/src/main/java/org/mapstruct/SubclassMapping.java b/core/src/main/java/org/mapstruct/SubclassMapping.java new file mode 100644 index 0000000000..4d635d8aa3 --- /dev/null +++ b/core/src/main/java/org/mapstruct/SubclassMapping.java @@ -0,0 +1,115 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.util.Experimental; + +/** + * Configures the mapping to handle hierarchy of the source type. + *

    + * The subclass to be mapped is to be specified via {@link #source()}. + * The subclass to map to is to be specified via {@link #target()}. + *

    + *

    + * This annotation can be combined with @Mapping annotations. + *

    + * + *
    
    + * @Mapper
    + * public interface MyMapper {
    + *    @SubclassMapping (target = TargetSubclass.class, source = SourceSubclass.class)
    + *    TargetParent mapParent(SourceParent parent);
    + *
    + *    TargetSubclass mapSubclass(SourceSubclass subInstant);
    + * }
    + * 
    + * Below follow examples of the implementation for the mapParent method. + * Example 1: For parents that cannot be created. (e.g. abstract classes or interfaces) + *
    
    + * // generates
    + * @Override
    + * public TargetParent mapParent(SourceParent parent) {
    + *     if (parent instanceof SourceSubclass) {
    + *         return mapSubclass( (SourceSubclass) parent );
    + *     }
    + *     else {
    + *         throw new IllegalArgumentException("Not all subclasses are supported for this mapping. Missing for "
    + *                    + parent.getClass());
    + *     }
    + * }
    + * 
    + * Example 2: For parents that can be created. (e.g. normal classes or interfaces with + * @Mapper( uses = ObjectFactory.class ) ) + *
    
    + * // generates
    + * @Override
    + * public TargetParent mapParent(SourceParent parent) {
    + *     TargetParent targetParent1;
    + *     if (parent instanceof SourceSubclass) {
    + *         targetParent1 = mapSubclass( (SourceSubclass) parent );
    + *     }
    + *     else {
    + *         targetParent1 = new TargetParent();
    + *         // ...
    + *     }
    + * }
    + * 
    + * + * @author Ben Zegveld + * @since 1.5 + */ +@Repeatable(value = SubclassMappings.class) +@Retention(RetentionPolicy.CLASS) +@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +@Experimental +public @interface SubclassMapping { + + /** + * The source subclass to check for before using the default mapping as fallback. + * + * @return the source subclass to check for before using the default mapping as fallback. + */ + Class source(); + + /** + * The target subclass to map the source to. + * + * @return the target subclass to map the source to. + */ + Class target(); + + /** + * A qualifier can be specified to aid the selection process of a suitable mapper. This is useful in case multiple + * mapping methods (hand written or generated) qualify and thus would result in an 'Ambiguous mapping methods found' + * error. A qualifier is a custom annotation and can be placed on a hand written mapper class or a method. + * + * @return the qualifiers + * @see Qualifier + */ + Class[] qualifiedBy() default {}; + + /** + * String-based form of qualifiers; When looking for a suitable mapping method for a given property, MapStruct will + * only consider those methods carrying directly or indirectly (i.e. on the class-level) a {@link Named} annotation + * for each of the specified qualifier names. + *

    + * Note that annotation-based qualifiers are generally preferable as they allow more easily to find references and + * are safe for refactorings, but name-based qualifiers can be a less verbose alternative when requiring a large + * number of qualifiers as no custom annotation types are needed. + * + * @return One or more qualifier name(s) + * @see #qualifiedBy() + * @see Named + */ + String[] qualifiedByName() default {}; +} diff --git a/core/src/main/java/org/mapstruct/SubclassMappings.java b/core/src/main/java/org/mapstruct/SubclassMappings.java new file mode 100644 index 0000000000..d6aac264d4 --- /dev/null +++ b/core/src/main/java/org/mapstruct/SubclassMappings.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.util.Experimental; + +/** + * Configures the SubclassMappings of several subclasses. + *

    + * TIP: When using java 8 or later, you can omit the @SubclassMappings + * Wrapper annotation and directly specify several @SubclassMapping annotations + * on one method. + *

    + *

    These two examples are equal. + *

    + *
    
    + * // before java 8
    + * @Mapper
    + * public interface MyMapper {
    + *     @SubclassMappings({
    + *         @SubclassMapping(source = FirstSub.class, target = FirstTargetSub.class),
    + *         @SubclassMapping(source = SecondSub.class, target = SecondTargetSub.class)
    + *     })
    + *     ParentTarget toParentTarget(Parent parent);
    + * }
    + * 
    + *
    
    + * // java 8 and later
    + * @Mapper
    + * public interface MyMapper {
    + *     @SubclassMapping(source = First.class, target = FirstTargetSub.class),
    + *     @SubclassMapping(source = SecondSub.class, target = SecondTargetSub.class)
    + *     ParentTarget toParentTarget(Parent parent);
    + * }
    + * 
    + * + * @author Ben Zegveld + * @since 1.5 + */ +@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE }) +@Retention(RetentionPolicy.CLASS) +@Experimental +public @interface SubclassMappings { + + /** + * The subclassMappings that should be applied. + * + * @return the subclassMappings to apply. + */ + SubclassMapping[] value(); + +} diff --git a/core/src/main/java/org/mapstruct/TargetPropertyName.java b/core/src/main/java/org/mapstruct/TargetPropertyName.java new file mode 100644 index 0000000000..c7ab8d957d --- /dev/null +++ b/core/src/main/java/org/mapstruct/TargetPropertyName.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This annotation marks a presence check method parameter as a target property name parameter. + *

    + * This parameter enables conditional filtering based on target property name at run-time. + * Parameter must be of type {@link String} and can be present only in {@link Condition} method. + *

    + * @author Nikola Ivačič + * @since 1.6 + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.CLASS) +public @interface TargetPropertyName { +} diff --git a/core/src/main/java/org/mapstruct/TargetType.java b/core/src/main/java/org/mapstruct/TargetType.java new file mode 100644 index 0000000000..9d617fec0c --- /dev/null +++ b/core/src/main/java/org/mapstruct/TargetType.java @@ -0,0 +1,53 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Declares a parameter of a custom mapping method to be populated with the target type of the mapping. + *

    + * Not more than one parameter can be declared as {@code TargetType} and that parameter needs to be of type + * {@link Class} (may be parameterized), or a super-type of it. + * + *

    + * Example: + *

    + *
    
    + * public class EntityFactory {
    + *    public <T extends BaseEntity> T createEntity(@TargetType Class<T> entityClass) {
    + *         return // ... custom factory logic
    + *    }
    + * }
    + * @Mapper(uses = EntityFactory.class)
    + * public interface CarMapper {
    + *     CarEntity carDtoToCar(CarDto dto);
    + * }
    + * 
    + *
    
    + * // generates
    + * public class CarMapperImpl implements CarMapper {
    + *     private final EntityFactory entityFactory = new EntityFactory();
    + *     @Override
    + *     public CarEntity carDtoToCar(CarDto dto) {
    + *         if ( dto == null ) {
    + *             return null;
    + *         }
    + *         CarEntity carEntity = entityFactory.createEntity( CarEntity.class );
    + *         return carEntity;
    + *     }
    + * }
    + * 
    + * + * @author Andreas Gudian + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.CLASS) +public @interface TargetType { +} diff --git a/core/src/main/java/org/mapstruct/ValueMapping.java b/core/src/main/java/org/mapstruct/ValueMapping.java index 59bc10f3d5..7ad3726e48 100644 --- a/core/src/main/java/org/mapstruct/ValueMapping.java +++ b/core/src/main/java/org/mapstruct/ValueMapping.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @@ -30,20 +18,16 @@ *
      *
    1. Enumeration to Enumeration
    2. *
    - *

    - * Example 1: + * Example 1: * - *

    - * 
    - * public enum OrderType { RETAIL, B2B, EXTRA, STANDARD, NORMAL }
    + * 
    
    + * public enum OrderType { RETAIL, B2B, C2C, EXTRA, STANDARD, NORMAL }
      *
      * public enum ExternalOrderType { RETAIL, B2B, SPECIAL, DEFAULT }
      *
    - * @ValueMappings({
    - *    @ValueMapping(source = "EXTRA", target = "SPECIAL"),
    - *    @ValueMapping(source = "STANDARD", target = "DEFAULT"),
    - *    @ValueMapping(source = "NORMAL", target = "DEFAULT")
    - * })
    + * @ValueMapping(target = "SPECIAL", source = "EXTRA"),
    + * @ValueMapping(target = "DEFAULT", source = "STANDARD"),
    + * @ValueMapping(target = "DEFAULT", source = "NORMAL")
      * ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
      * 
      * Mapping result:
    @@ -59,18 +43,12 @@
      * +---------------------+----------------------------+
      * 
    * - * MapStruct will WARN on incomplete mappings. However, if for some reason no match is found an - * {@link java.lang.IllegalStateException} will be thrown. - *

    - * Example 2: + * Example 2: * - *

    - * 
    - * @ValueMappings({
    - *    @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ),
    - *    @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ),
    - *    @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" )
    - * })
    + * 
    
    + * @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ),
    + * @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ),
    + * @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" )
      * ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
      * 
      * Mapping result:
    @@ -86,12 +64,28 @@
      * +---------------------+----------------------------+
      * 
    * + * Example 3: + * + * MapStruct will WARN on incomplete mappings. However, if for some reason no match is found, an + * {@link java.lang.IllegalStateException} will be thrown. This compile-time error can be avoided by + * using {@link MappingConstants#THROW_EXCEPTION} for {@link ValueMapping#target()}. It will result an + * {@link java.lang.IllegalArgumentException} at runtime. + *
    
    + * @ValueMapping( source = "STANDARD", target = "DEFAULT" ),
    + * @ValueMapping( source = "C2C", target = MappingConstants.THROW_EXCEPTION )
    + * ExternalOrderType orderTypeToExternalOrderType(OrderType orderType);
    + * 
    + * Mapping result:
    + * {@link java.lang.IllegalArgumentException} with the error message:
    + * Unexpected enum constant: C2C
    + * 
    + * * @author Sjaak Derksen */ +@Repeatable(ValueMappings.class) @Retention(RetentionPolicy.CLASS) -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface ValueMapping { - /** * The source value constant to use for this mapping. * @@ -120,6 +114,7 @@ *
      *
    1. enum constant name
    2. *
    3. {@link MappingConstants#NULL}
    4. + *
    5. {@link MappingConstants#THROW_EXCEPTION}
    6. *
    * * @return The target value. diff --git a/core/src/main/java/org/mapstruct/ValueMappings.java b/core/src/main/java/org/mapstruct/ValueMappings.java index 5c720e834d..95d4c7d5ce 100644 --- a/core/src/main/java/org/mapstruct/ValueMappings.java +++ b/core/src/main/java/org/mapstruct/ValueMappings.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct; @@ -25,13 +12,43 @@ /** * Constructs a set of value (constant) mappings. + *

    + * TIP: When using Java 8 or later, you can omit the @ValueMappings + * wrapper annotation and directly specify several @ValueMapping annotations on one method. + * + *

    These two examples are equal

    + *
    
    + * // before Java 8
    + * @Mapper
    + * public interface GenderMapper {
    + *     @ValueMappings({
    + *         @ValueMapping(target = "M", source = "MALE"),
    + *         @ValueMapping(target = "F", source = "FEMALE")
    + *     })
    + *     GenderDto mapToDto(Gender gender);
    + * }
    + * 
    + *
    
    + * //Java 8 and later
    + * @Mapper
    + * public interface GenderMapper {
    + *     @ValueMapping(target = "M", source = "MALE"),
    + *     @ValueMapping(target = "F", source = "FEMALE")
    + *     GenderDto mapToDto(Gender gender);
    + * }
    + * 
    * * @author Sjaak Derksen */ -@Target(ElementType.METHOD) +@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.CLASS) public @interface ValueMappings { + /** + * The value mappings that should be applied. + * + * @return the value mappings + */ ValueMapping[] value(); } diff --git a/core/src/main/java/org/mapstruct/control/DeepClone.java b/core/src/main/java/org/mapstruct/control/DeepClone.java new file mode 100644 index 0000000000..a5264c861e --- /dev/null +++ b/core/src/main/java/org/mapstruct/control/DeepClone.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.control; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.mapstruct.util.Experimental; + +/** + * Clones a source type to a target type (assuming source and target are of the same type). + * + * @author Sjaak Derksen + * + * @since 1.4 + */ +@Retention(RetentionPolicy.CLASS) +@Experimental +@MappingControl( MappingControl.Use.MAPPING_METHOD ) +public @interface DeepClone { +} diff --git a/core/src/main/java/org/mapstruct/control/MappingControl.java b/core/src/main/java/org/mapstruct/control/MappingControl.java new file mode 100644 index 0000000000..12c95c4494 --- /dev/null +++ b/core/src/main/java/org/mapstruct/control/MappingControl.java @@ -0,0 +1,159 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.control; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Controls which means of mapping are considered between the source and the target in mappings. + * + *

    + * There are several applications of MappingControl conceivable. One application, "deep cloning" is + * explained below in the example. + *

    + * + *

    + * Another application is controlling so called "complex mappings", which are not always desirable and sometimes lead to + * unexpected behaviour and prolonged compilation time. + *

    + * + *

    Example:Cloning of an object

    + *

    + * When all methods are allowed, MapStruct would make a shallow copy. It would take the ShelveDTO in + * the FridgeDTO and directly enter that as target on the target FridgeDTO. By disabling all + * other kinds of mappings apart from {@link MappingControl.Use#MAPPING_METHOD}, see {@link DeepClone} MapStruct is + * forced to generate mapping methods all through the object graph `FridgeDTO` and hence create a deep clone. + *

    + *
    
    + * public class FridgeDTO {
    + *
    + *     private ShelveDTO shelve;
    + *
    + *     public ShelveDTO getShelve() {
    + *         return shelve;
    + *     }
    + *
    + *     public void setShelve(ShelveDTO shelve) {
    + *         this.shelve = shelve;
    + *     }
    + * }
    + * 
    + *
    
    + * public class ShelveDTO {
    + *
    + *     private CoolBeerDTO coolBeer;
    + *
    + *     public CoolBeerDTO getCoolBeer() {
    + *         return coolBeer;
    + *     }
    + *
    + *     public void setCoolBeer(CoolBeerDTO coolBeer) {
    + *         this.coolBeer = coolBeer;
    + *     }
    + * }
    + * 
    + *
    
    + * public class CoolBeerDTO {
    + *
    + *     private String beerCount;
    + *
    + *     public String getBeerCount() {
    + *         return beerCount;
    + *     }
    + *
    + *     public void setBeerCount(String beerCount) {
    + *         this.beerCount = beerCount;
    + *     }
    + * }
    + * 
    + * + *
    
    + * @Mapper(mappingControl = DeepClone.class)
    + * public interface CloningMapper {
    + *
    + *     CloningMapper INSTANCE = Mappers.getMapper( CloningMapper.class );
    + *
    + *     FridgeDTO clone(FridgeDTO in);
    + *
    + * }
    + * 
    + * + * @author Sjaak Derksen + * + * @since 1.4 + */ +@Retention(RetentionPolicy.CLASS) +@Repeatable(MappingControls.class) +@Target( ElementType.ANNOTATION_TYPE ) +@MappingControl( MappingControl.Use.DIRECT ) +@MappingControl( MappingControl.Use.BUILT_IN_CONVERSION ) +@MappingControl( MappingControl.Use.MAPPING_METHOD ) +@MappingControl( MappingControl.Use.COMPLEX_MAPPING ) +public @interface MappingControl { + + /** + * The type of mapping control that should be used. + * + * @return What should be used for the mapping control + */ + Use value(); + + /** + * Defines the options that can be used for the mapping control. + */ + enum Use { + + /** + * Controls the mapping, allows for type conversion from source type to target type + *

    + * Type conversions are typically supported directly in Java. The "toString()" is such an example, + * which allows for mapping for instance a {@link java.lang.Number} type to a {@link java.lang.String}. + *

    + * Please refer to the MapStruct guide for more info. + * + * @since 1.4 + */ + BUILT_IN_CONVERSION, + + /** + * Controls the mapping from source to target type, allows mapping by calling: + *

      + *
    1. A type conversion, passed into a mapping method
    2. + *
    3. A mapping method, passed into a type conversion
    4. + *
    5. A mapping method passed into another mapping method
    6. + *
    + * + * @since 1.4 + */ + COMPLEX_MAPPING, + /** + * Controls the mapping, allows for a direct mapping from source type to target type. + *

    + * This means if source type and target type are of the same type, MapStruct will not perform + * any mappings anymore and assign the target to the source direct. + *

    + * An exception are types from the package {@code java}, which will be mapped always directly. + * + * @since 1.4 + */ + DIRECT, + + /** + * Controls the mapping, allows for Direct Mapping from source type to target type. + *

    + * The mapping method can be either a custom referred mapping method, or a MapStruct built in + * mapping method. + * + * @since 1.4 + */ + MAPPING_METHOD + } + +} diff --git a/core/src/main/java/org/mapstruct/control/MappingControls.java b/core/src/main/java/org/mapstruct/control/MappingControls.java new file mode 100644 index 0000000000..c1663e551e --- /dev/null +++ b/core/src/main/java/org/mapstruct/control/MappingControls.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.control; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Allows multiple {@link MappingControl} on a class declaration. + * + * @author Sjaak Derksen + * + * @since 1.4 + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.ANNOTATION_TYPE) +public @interface MappingControls { + + /** + * The mapping controls that should be applied to the annotated class. + * + * @return The mapping controls that should be applied to the annotated class. + */ + MappingControl[] value(); +} diff --git a/core/src/main/java/org/mapstruct/control/NoComplexMapping.java b/core/src/main/java/org/mapstruct/control/NoComplexMapping.java new file mode 100644 index 0000000000..5894f602a5 --- /dev/null +++ b/core/src/main/java/org/mapstruct/control/NoComplexMapping.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.control; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.mapstruct.util.Experimental; + +/** + * Disables complex mappings, mappings that require 2 mapping means (method, built-in conversion) to constitute + * a mapping from source to target. + * + * @see MappingControl.Use#COMPLEX_MAPPING + * + * @author Sjaak Derksen + * + * @since 1.4 + */ +@Retention(RetentionPolicy.CLASS) +@Experimental +@MappingControl( MappingControl.Use.DIRECT ) +@MappingControl( MappingControl.Use.BUILT_IN_CONVERSION ) +@MappingControl( MappingControl.Use.MAPPING_METHOD ) +public @interface NoComplexMapping { +} diff --git a/core/src/main/java/org/mapstruct/factory/Mappers.java b/core/src/main/java/org/mapstruct/factory/Mappers.java new file mode 100644 index 0000000000..d20bd59fa3 --- /dev/null +++ b/core/src/main/java/org/mapstruct/factory/Mappers.java @@ -0,0 +1,168 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.factory; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; + +import org.mapstruct.Mapper; + +/** + * Factory for obtaining mapper instances if no explicit component model such as CDI is configured via + * {@link Mapper#componentModel()}. + *

    + * Mapper implementation types are expected to have the same fully qualified name as their interface type, with the + * suffix {@code Impl} appended. When using this factory, mapper types - and any mappers they use - are instantiated by + * invoking their public no-args constructor. + *

    + * By convention, a single instance of each mapper is retrieved from the factory and exposed on the mapper interface + * type by declaring a member named {@code INSTANCE} like this: + * + *

    + * @Mapper
    + * public interface CustomerMapper {
    + *
    + *     CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class );
    + *
    + *     // mapping methods...
    + * }
    + * 
    + * + * @author Gunnar Morling + */ +public class Mappers { + + private static final String IMPLEMENTATION_SUFFIX = "Impl"; + + private Mappers() { + } + + /** + * Returns an instance of the given mapper type. + * + * @param clazz The type of the mapper to return. + * @param The type of the mapper to create. + * + * @return An instance of the given mapper type. + */ + public static T getMapper(Class clazz) { + try { + List classLoaders = collectClassLoaders( clazz.getClassLoader() ); + + return getMapper( clazz, classLoaders ); + } + catch ( ClassNotFoundException | NoSuchMethodException e ) { + throw new RuntimeException( e ); + } + } + + private static T getMapper(Class mapperType, Iterable classLoaders) + throws ClassNotFoundException, NoSuchMethodException { + + for ( ClassLoader classLoader : classLoaders ) { + T mapper = doGetMapper( mapperType, classLoader ); + if ( mapper != null ) { + return mapper; + } + } + + throw new ClassNotFoundException("Cannot find implementation for " + mapperType.getName() ); + } + + private static T doGetMapper(Class clazz, ClassLoader classLoader) throws NoSuchMethodException { + try { + @SuppressWarnings( "unchecked" ) + Class implementation = (Class) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ); + Constructor constructor = implementation.getDeclaredConstructor(); + constructor.setAccessible( true ); + + return constructor.newInstance(); + } + catch ( ClassNotFoundException e ) { + return getMapperFromServiceLoader( clazz, classLoader ); + } + catch ( InstantiationException | InvocationTargetException | IllegalAccessException e ) { + throw new RuntimeException( e ); + } + } + + /** + * Returns the class of the implementation for the given mapper type. + * + * @param clazz The type of the mapper to return. + * @param The type of the mapper to create. + * + * @return A class of the implementation for the given mapper type. + * + * @since 1.3 + */ + public static Class getMapperClass(Class clazz) { + try { + List classLoaders = collectClassLoaders( clazz.getClassLoader() ); + + return getMapperClass( clazz, classLoaders ); + } + catch ( ClassNotFoundException e ) { + throw new RuntimeException( e ); + } + } + + private static Class getMapperClass(Class mapperType, Iterable classLoaders) + throws ClassNotFoundException { + + for ( ClassLoader classLoader : classLoaders ) { + Class mapperClass = doGetMapperClass( mapperType, classLoader ); + if ( mapperClass != null ) { + return mapperClass; + } + } + + throw new ClassNotFoundException( "Cannot find implementation for " + mapperType.getName() ); + } + + @SuppressWarnings("unchecked") + private static Class doGetMapperClass(Class clazz, ClassLoader classLoader) { + try { + return (Class) classLoader.loadClass( clazz.getName() + IMPLEMENTATION_SUFFIX ); + } + catch ( ClassNotFoundException e ) { + T mapper = getMapperFromServiceLoader( clazz, classLoader ); + if ( mapper != null ) { + return (Class) mapper.getClass(); + } + + return null; + } + } + + private static T getMapperFromServiceLoader(Class clazz, ClassLoader classLoader) { + ServiceLoader loader = ServiceLoader.load( clazz, classLoader ); + + for ( T mapper : loader ) { + if ( mapper != null ) { + return mapper; + } + } + + return null; + } + + private static List collectClassLoaders(ClassLoader classLoader) { + List classLoaders = new ArrayList<>( 3 ); + classLoaders.add( classLoader ); + + if ( Thread.currentThread().getContextClassLoader() != null ) { + classLoaders.add( Thread.currentThread().getContextClassLoader() ); + } + + classLoaders.add( Mappers.class.getClassLoader() ); + + return classLoaders; + } +} diff --git a/core/src/main/java/org/mapstruct/factory/package-info.java b/core/src/main/java/org/mapstruct/factory/package-info.java new file mode 100644 index 0000000000..532857a401 --- /dev/null +++ b/core/src/main/java/org/mapstruct/factory/package-info.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + *

    + * Provides the {@link org.mapstruct.factory.Mappers} factory class for the retrieval of mapper instances if no + * explicit component model such as CDI is configured via {@link org.mapstruct.Mapper#componentModel()}. + *

    + * + */ +package org.mapstruct.factory; diff --git a/core/src/main/java/org/mapstruct/package-info.java b/core/src/main/java/org/mapstruct/package-info.java new file mode 100644 index 0000000000..5a53b5a6d3 --- /dev/null +++ b/core/src/main/java/org/mapstruct/package-info.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + *

    + * MapStruct is a code generator which simplifies the implementation of mappings between Java bean types by generating + * mapping code at compile time, following a convention-over-configuration approach. The generated code uses plain + * method invocations and thus is fast and type-safe. + *

    + *

    + * This package contains several annotations which allow to configure how mapper interfaces are generated. + *

    + * + * @see MapStruct reference documentation + */ +package org.mapstruct; diff --git a/core/src/main/java/org/mapstruct/util/Experimental.java b/core/src/main/java/org/mapstruct/util/Experimental.java new file mode 100644 index 0000000000..5fd5eb3b5c --- /dev/null +++ b/core/src/main/java/org/mapstruct/util/Experimental.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.util; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Features that are marked with this annotation are considered experimental. + * + * @author Andreas Gudian + */ +@Documented +@Retention(RetentionPolicy.SOURCE) +public @interface Experimental { + + /** + * The reason why the feature is considered experimental. + * + * @return the reason why the feature is considered experimental. + */ + String value() default ""; +} diff --git a/core/src/test/java/org/mapstruct/factory/MappersTest.java b/core/src/test/java/org/mapstruct/factory/MappersTest.java new file mode 100644 index 0000000000..cde4b5be3b --- /dev/null +++ b/core/src/test/java/org/mapstruct/factory/MappersTest.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.factory; + +import org.junit.jupiter.api.Test; +import org.mapstruct.test.model.Foo; +import org.mapstruct.test.model.SomeClass; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Unit test for {@link Mappers}. + * + * @author Gunnar Morling + */ +public class MappersTest { + + @Test + public void shouldReturnImplementationInstance() { + + Foo mapper = Mappers.getMapper( Foo.class ); + assertThat( mapper ).isNotNull(); + } + + @Test + public void shouldReturnImplementationClass() { + + Class mapperClass = Mappers.getMapperClass( Foo.class ); + assertThat( mapperClass ).isNotNull(); + assertThat( mapperClass ).isNotExactlyInstanceOf( Foo.class ); + } + + /** + * Checks if an implementation of a nested mapper can be found. This is a special case since + * it is named + */ + @Test + public void findsNestedMapperImpl() { + assertThat( Mappers.getMapper( SomeClass.Foo.class ) ).isNotNull(); + assertThat( Mappers.getMapper( SomeClass.NestedClass.Foo.class ) ).isNotNull(); + } + + @Test + public void findsNestedMapperImplClass() { + assertThat( Mappers.getMapperClass( SomeClass.Foo.class ) ).isNotNull(); + assertThat( Mappers.getMapperClass( SomeClass.NestedClass.Foo.class ) ).isNotNull(); + } + + @Test + public void shouldReturnPackagePrivateImplementationInstance() { + assertThat( Mappers.getMapper( PackagePrivateMapper.class ) ).isNotNull(); + } + + @Test + public void shouldReturnPackagePrivateImplementationClass() { + assertThat( Mappers.getMapperClass( PackagePrivateMapper.class ) ).isNotNull(); + } +} diff --git a/core/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java b/core/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java new file mode 100644 index 0000000000..4fbc97f26d --- /dev/null +++ b/core/src/test/java/org/mapstruct/factory/PackagePrivateMapper.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.factory; + +interface PackagePrivateMapper { + +} diff --git a/core/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java b/core/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java new file mode 100644 index 0000000000..2aca92abef --- /dev/null +++ b/core/src/test/java/org/mapstruct/factory/PackagePrivateMapperImpl.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.factory; + +class PackagePrivateMapperImpl implements PackagePrivateMapper { +} diff --git a/core/src/test/java/org/mapstruct/test/model/Foo.java b/core/src/test/java/org/mapstruct/test/model/Foo.java new file mode 100644 index 0000000000..4ee788efcf --- /dev/null +++ b/core/src/test/java/org/mapstruct/test/model/Foo.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.test.model; + +public interface Foo { + +} diff --git a/core/src/test/java/org/mapstruct/test/model/FooImpl.java b/core/src/test/java/org/mapstruct/test/model/FooImpl.java new file mode 100644 index 0000000000..0d90dabebc --- /dev/null +++ b/core/src/test/java/org/mapstruct/test/model/FooImpl.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.test.model; + +public class FooImpl implements Foo { + +} diff --git a/core/src/test/java/org/mapstruct/test/model/SomeClass$FooImpl.java b/core/src/test/java/org/mapstruct/test/model/SomeClass$FooImpl.java new file mode 100644 index 0000000000..a9e03641fe --- /dev/null +++ b/core/src/test/java/org/mapstruct/test/model/SomeClass$FooImpl.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.test.model; + +/** + * For testing naming of implementations of nested mappers (issue 611). + * + * @author Tillmann Gaida + */ +/* + * Turn off checkstyle since the underscore introduced by issue 611 violates the class naming + * convention. + */ +// CHECKSTYLE:OFF +public class SomeClass$FooImpl implements SomeClass.Foo { + +} diff --git a/core/src/test/java/org/mapstruct/test/model/SomeClass$NestedClass$FooImpl.java b/core/src/test/java/org/mapstruct/test/model/SomeClass$NestedClass$FooImpl.java new file mode 100644 index 0000000000..53331de181 --- /dev/null +++ b/core/src/test/java/org/mapstruct/test/model/SomeClass$NestedClass$FooImpl.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.test.model; + +/** + * For testing naming of implementations of nested mappers (issue 611). + * + * @author Tillmann Gaida + */ +/* + * Turn off checkstyle since the underscore introduced by issue 611 violates the class naming + * convention. + */ +// CHECKSTYLE:OFF +public class SomeClass$NestedClass$FooImpl implements SomeClass.NestedClass.Foo { + +} diff --git a/core/src/test/java/org/mapstruct/test/model/SomeClass.java b/core/src/test/java/org/mapstruct/test/model/SomeClass.java new file mode 100644 index 0000000000..d25841145c --- /dev/null +++ b/core/src/test/java/org/mapstruct/test/model/SomeClass.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.test.model; + +/** + * The sole purpose of this class is to have a place to nest the Foo interface. + * + * @author Tillmann Gaida + */ +public class SomeClass { + public interface Foo { } + + public static class NestedClass { + public interface Foo { } + } +} diff --git a/distribution/pom.xml b/distribution/pom.xml index e155e87b15..b480e24a06 100644 --- a/distribution/pom.xml +++ b/distribution/pom.xml @@ -1,22 +1,9 @@ @@ -25,7 +12,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml @@ -38,10 +25,6 @@ org.mapstruct mapstruct - - org.mapstruct - mapstruct-jdk8 - org.mapstruct mapstruct-processor @@ -51,6 +34,23 @@ org.freemarker freemarker + + + org.mapstruct.tools.gem + gem-api + + + + org.jetbrains.kotlin + kotlin-metadata-jvm + + + + jakarta.xml.bind + jakarta.xml.bind-api + provided + true + @@ -71,7 +71,7 @@ org.freemarker freemarker ${project.build.directory}/freemarker-unpacked - META-INF/LICENSE.txt,META-INF/NOTICE.txt + META-INF/LICENSE @@ -95,18 +95,17 @@ maven-javadoc-plugin - ${basedir}/../core-common/src/main/java; ${basedir}/../core/src/main/java; ${basedir}/../processor/src/main/java - http://docs.oracle.com/javase/7/docs/api/ + https://docs.oracle.com/javase/8/docs/api/ MapStruct Packages MapStruct ${project.version} MapStruct ${project.version} - Gunnar Morling; All rights reserved. Released under the Apache Software License 2.0.]]> + MapStruct Authors; All rights reserved. Released under the Apache Software License 2.0.]]> @@ -114,18 +113,16 @@ MapStruct API org.mapstruct* + + MapStruct Processor SPI + org.mapstruct.ap.spi* + MapStruct Processor org.mapstruct.ap* - org.jboss.apiviz.APIviz - - org.jboss.apiviz - apiviz - 1.3.2.GA - true UTF-8 UTF-8 @@ -134,6 +131,23 @@ true true true + + + + + if (typeof useModuleDirectories !== 'undefined') { + useModuleDirectories = false; + } + + ]]> + + --allow-script-in-comments + @@ -153,7 +167,7 @@ ${basedir}/src/main/assembly/dist.xml mapstruct-${project.version} - gnu + posix @@ -174,4 +188,21 @@ + + + + jdk-11-or-newer + + [11 + + + + javax.xml.bind + jaxb-api + provided + true + + + + diff --git a/distribution/src/main/assembly/dist.xml b/distribution/src/main/assembly/dist.xml index 88aed5eeb2..e0bc00496b 100644 --- a/distribution/src/main/assembly/dist.xml +++ b/distribution/src/main/assembly/dist.xml @@ -1,22 +1,9 @@ @@ -32,7 +19,6 @@ lib org.mapstruct:mapstruct - org.mapstruct:mapstruct-jdk8 org.mapstruct:mapstruct-processor @@ -56,11 +42,7 @@ / - target/freemarker-unpacked/META-INF/NOTICE.txt - / - - - target/freemarker-unpacked/META-INF/LICENSE.txt + target/freemarker-unpacked/META-INF/LICENSE etc/freemarker @@ -94,7 +76,7 @@ - target/site/apidocs + target/reports/apidocs docs/api diff --git a/documentation/pom.xml b/documentation/pom.xml index 4802c6149f..21a2b151bd 100644 --- a/documentation/pom.xml +++ b/documentation/pom.xml @@ -1,22 +1,9 @@ @@ -25,7 +12,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml @@ -34,9 +21,9 @@ MapStruct Documentation - 1.5.0-alpha.11 - 1.5.4 - 1.7.21 + 1.6.0 + 2.5.1 + 9.2.17.0 @@ -46,7 +33,7 @@ org.asciidoctor asciidoctor-maven-plugin - 1.5.3 + 2.1.0 org.asciidoctor @@ -65,7 +52,6 @@ - coderay mapstruct-reference-guide.asciidoc ${project.version} diff --git a/documentation/src/main/asciidoc/chapter-1-introduction.asciidoc b/documentation/src/main/asciidoc/chapter-1-introduction.asciidoc new file mode 100644 index 0000000000..1d73a11078 --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-1-introduction.asciidoc @@ -0,0 +1,16 @@ +[[introduction]] +== Introduction + +MapStruct is a Java http://docs.oracle.com/javase/6/docs/technotes/guides/apt/index.html[annotation processor] for the generation of type-safe bean mapping classes. + +All you have to do is to define a mapper interface which declares any required mapping methods. During compilation, MapStruct will generate an implementation of this interface. This implementation uses plain Java method invocations for mapping between source and target objects, i.e. no reflection or similar. + +Compared to writing mapping code from hand, MapStruct saves time by generating code which is tedious and error-prone to write. Following a convention over configuration approach, MapStruct uses sensible defaults but steps out of your way when it comes to configuring or implementing special behavior. + +Compared to dynamic mapping frameworks, MapStruct offers the following advantages: + +* Fast execution by using plain method invocations instead of reflection +* Compile-time type safety: Only objects and attributes mapping to each other can be mapped, no accidental mapping of an order entity into a customer DTO etc. +* Clear error-reports at build time, if +** mappings are incomplete (not all target properties are mapped) +** mappings are incorrect (cannot find a proper mapping method or type conversion) diff --git a/documentation/src/main/asciidoc/chapter-10-advanced-mapping-options.asciidoc b/documentation/src/main/asciidoc/chapter-10-advanced-mapping-options.asciidoc new file mode 100644 index 0000000000..306169193d --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-10-advanced-mapping-options.asciidoc @@ -0,0 +1,667 @@ +== Advanced mapping options +This chapter describes several advanced options which allow to fine-tune the behavior of the generated mapping code as needed. + +[[default-values-and-constants]] +=== Default values and constants + +Default values can be specified to set a predefined value to a target property if the corresponding source property is `null`. Constants can be specified to set such a predefined value in any case. Default values and constants are specified as String values. When the target type is a primitive or a boxed type, the String value is taken literal. Bit / octal / decimal / hex patterns are allowed in such a case as long as they are a valid literal. +In all other cases, constant or default values are subject to type conversion either via built-in conversions or the invocation of other mapping methods in order to match the type required by the target property. + +A mapping with a constant must not include a reference to a source property. The following example shows some mappings using default values and constants: + +.Mapping method with default values and constants +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(uses = StringListMapper.class) +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping(target = "stringProperty", source = "stringProp", defaultValue = "undefined") + @Mapping(target = "longProperty", source = "longProp", defaultValue = "-1") + @Mapping(target = "stringConstant", constant = "Constant Value") + @Mapping(target = "integerConstant", constant = "14") + @Mapping(target = "longWrapperConstant", constant = "3001") + @Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014") + @Mapping(target = "stringListConstants", constant = "jack-jill-tom") + Target sourceToTarget(Source s); +} +---- +==== + +If `s.getStringProp() == null`, then the target property `stringProperty` will be set to `"undefined"` instead of applying the value from `s.getStringProp()`. If `s.getLongProperty() == null`, then the target property `longProperty` will be set to `-1`. +The String `"Constant Value"` is set as is to the target property `stringConstant`. The value `"3001"` is type-converted to the `Long` (wrapper) class of target property `longWrapperConstant`. Date properties also require a date format. The constant `"jack-jill-tom"` demonstrates how the hand-written class `StringListMapper` is invoked to map the dash-separated list into a `List`. + +[[expressions]] +=== Expressions + +By means of Expressions it will be possible to include constructs from a number of languages. + +Currently only Java is supported as a language. This feature is e.g. useful to invoke constructors. The entire source object is available for usage in the expression. Care should be taken to insert only valid Java code: MapStruct will not validate the expression at generation-time, but errors will show up in the generated classes during compilation. + +The example below demonstrates how two source properties can be mapped to one target: + +.Mapping method using an expression +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping(target = "timeAndFormat", + expression = "java( new org.sample.TimeAndFormat( s.getTime(), s.getFormat() ) )") + Target sourceToTarget(Source s); +} +---- +==== + +The example demonstrates how the source properties `time` and `format` are composed into one target property `TimeAndFormat`. Please note that the fully qualified package name is specified because MapStruct does not take care of the import of the `TimeAndFormat` class (unless it's used otherwise explicitly in the `SourceTargetMapper`). This can be resolved by defining `imports` on the `@Mapper` annotation. + +.Declaring an import +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +imports org.sample.TimeAndFormat; + +@Mapper( imports = TimeAndFormat.class ) +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping(target = "timeAndFormat", + expression = "java( new TimeAndFormat( s.getTime(), s.getFormat() ) )") + Target sourceToTarget(Source s); +} +---- +==== + +[[default-expressions]] +=== Default Expressions + +Default expressions are a combination of default values and expressions. They will only be used when the source attribute is `null`. + +The same warnings and restrictions apply to default expressions that apply to expressions. Only Java is supported, and MapStruct will not validate the expression at generation-time. + +The example below demonstrates how a default expression can be used to set a value when the source attribute is not present (e.g. is `null`): + +.Mapping method using a default expression +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +imports java.util.UUID; + +@Mapper( imports = UUID.class ) +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping(target="id", source="sourceId", defaultExpression = "java( UUID.randomUUID().toString() )") + Target sourceToTarget(Source s); +} +---- +==== + +The example demonstrates how to use defaultExpression to set an `ID` field if the source field is null, this could be used to take the existing `sourceId` from the source object if it is set, or create a new `Id` if it isn't. Please note that the fully qualified package name is specified because MapStruct does not take care of the import of the `UUID` class (unless it’s used otherwise explicitly in the `SourceTargetMapper`). This can be resolved by defining imports on the @Mapper annotation (see <>). + +[[sub-class-mappings]] +=== Subclass Mapping + +When both input and result types have an inheritance relation, you would want the correct specialization be mapped to the matching specialization. +Suppose an `Apple` and a `Banana`, which are both specializations of `Fruit`. + +.Specifying the sub class mappings of a fruit mapping +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface FruitMapper { + + @SubclassMapping( source = AppleDto.class, target = Apple.class ) + @SubclassMapping( source = BananaDto.class, target = Banana.class ) + Fruit map( FruitDto source ); + +} +---- +==== + +If you would just use a normal mapping both the `AppleDto` and the `BananaDto` would be made into a `Fruit` object, instead of an `Apple` and a `Banana` object. +By using the subclass mapping an `AppleDtoToApple` mapping will be used for `AppleDto` objects, and an `BananaDtoToBanana` mapping will be used for `BananaDto` objects. +If you try to map a `GrapeDto` it would still turn it into a `Fruit`. + +In the case that the `Fruit` is an abstract class or an interface, you would get a compile error. + +To allow mappings for abstract classes or interfaces you need to set the `subclassExhaustiveStrategy` to `RUNTIME_EXCEPTION`, you can do this at the `@MapperConfig`, `@Mapper` or `@BeanMapping` annotations. If you then pass a `GrapeDto` an `IllegalArgumentException` will be thrown because it is unknown how to map a `GrapeDto`. +Adding the missing (`@SubclassMapping`) for it will fix that. + +<> can be used to further control which methods may be chosen to map a specific subclass. For that, you will need to use one of `SubclassMapping#qualifiedByName` or `SubclassMapping#qualifiedBy`. + +[TIP] +==== +If the mapping method for the subclasses does not exist it will be created and any other annotations on the fruit mapping method will be inherited by the newly generated mappings. +==== + +[NOTE] +==== +Combining `@SubclassMapping` with update methods is not supported. +If you try to use subclass mappings there will be a compile error. +The same issue exists for the `@Context` and `@TargetType` parameters. +==== + +[[determining-result-type]] +=== Determining the result type + +When result types have an inheritance relation, selecting either mapping method (`@Mapping`) or a factory method (`@BeanMapping`) can become ambiguous. Suppose an Apple and a Banana, which are both specializations of Fruit. + +.Specifying the result type of a bean mapping method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper( uses = FruitFactory.class ) +public interface FruitMapper { + + @BeanMapping( resultType = Apple.class ) + Fruit map( FruitDto source ); + +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class FruitFactory { + + public Apple createApple() { + return new Apple( "Apple" ); + } + + public Banana createBanana() { + return new Banana( "Banana" ); + } +} +---- +==== + +So, which `Fruit` must be factorized in the mapping method `Fruit map(FruitDto source);`? A `Banana` or an `Apple`? Here's where the `@BeanMapping#resultType` comes in handy. It controls the factory method to select, or in absence of a factory method, the return type to create. + +[TIP] +==== +The same mechanism is present on mapping: `@Mapping#resultType` and works like you expect it would: it selects the mapping method with the desired result type when present. +==== + +[TIP] +==== +The mechanism is also present on iterable mapping and map mapping. `@IterableMapping#elementTargetType` is used to select the mapping method with the desired element in the resulting `Iterable`. For the `@MapMapping` a similar purpose is served by means of `#MapMapping#keyTargetType` and `MapMapping#valueTargetType`. +==== + +[[mapping-result-for-null-arguments]] +=== Controlling mapping result for 'null' arguments + +MapStruct offers control over the object to create when the source argument of the mapping method equals `null`. +By default `null` will be returned, or `Optional.empty()` if the return type is `Optional`. + +However, by specifying `nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT` on `@BeanMapping`, `@IterableMapping`, `@MapMapping`, or globally on `@Mapper` or `@MapperConfig`, the mapping result can be altered to return empty *default* values. This means for: + +* *Bean mappings*: an 'empty' target bean will be returned, with the exception of constants and expressions, they will be populated when present. +* *Iterables / Arrays*: an empty iterable will be returned. +* *Maps*: an empty map will be returned. + +The strategy works in a hierarchical fashion. Setting `nullValueMappingStrategy` on mapping method level will override `@Mapper#nullValueMappingStrategy`, and `@Mapper#nullValueMappingStrategy` will override `@MapperConfig#nullValueMappingStrategy`. + +[[mapping-result-for-null-collection-or-map-arguments]] +=== Controlling mapping result for 'null' collection or map arguments + +With <> it is possible to control how the return type should be constructed when the source argument of the mapping method is `null`. +That is applied for all mapping methods (bean, iterable or map mapping methods). + +However, MapStruct also offers a more dedicated way to control how collections / maps should be mapped. +e.g. return default (empty) collections / maps, but return `null` for beans. + +For collections (iterables) this can be controlled through: + +* `MapperConfig#nullValueIterableMappingStrategy` +* `Mapper#nullValueIterableMappingStrategy` +* `IterableMapping#nullValueMappingStrategy` + +For maps this can be controlled through: + +* `MapperConfig#nullValueMapMappingStrategy` +* `Mapper#nullValueMapMappingStrategy` +* `MapMapping#nullValueMappingStrategy` + +How the value of the `NullValueMappingStrategy` is applied is the same as in <> + + +[[mapping-result-for-null-properties]] +=== Controlling mapping result for 'null' properties in bean mappings (update mapping methods only). + +MapStruct offers control over the property to set in an `@MappingTarget` annotated target bean when the source property equals `null` or the presence check method results in 'absent'. + +By default the target property will be set to `null`, or `Optional.empty()` if the target property is `Optional`. + +However: + +1. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MapperConfig`, the mapping result can be altered to return *default* values. +For `List` MapStruct generates an `ArrayList`, for `Map` a `LinkedHashMap`, for arrays an empty array, for `String` `""` and for primitive / boxed types a representation of `false` or `0`. +For all other objects an new instance is created. Please note that a default constructor is required. If not available, use the `@Mapping#defaultValue`. + +2. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MapperConfig`, the mapping result will be equal to the original value of the `@MappingTarget` annotated target. + +3. By specifying `nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR` on `@Mapping`, `@BeanMapping`, `@Mapper` or `@MapperConfig`, the target collection or map will be cleared when the source property is `null`. +This strategy only applies to `Collection` and `Map` target properties. + +The strategy works in a hierarchical fashion. Setting `nullValuePropertyMappingStrategy` on mapping method level will override `@Mapper#nullValuePropertyMappingStrategy`, and `@Mapper#nullValuePropertyMappingStrategy` will override `@MapperConfig#nullValuePropertyMappingStrategy`. + +[NOTE] +==== +Some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder as target accessor (see `CollectionMappingStrategy`), MapStruct will always generate a source property +null check, regardless of the value of the `NullValuePropertyMappingStrategy`, to avoid addition of `null` to the target collection or map. Since the target is assumed to be initialised this strategy will not be applied. +==== + +[TIP] +==== +`NullValuePropertyMappingStrategy` also applies when the presence checker returns `not present`. +==== + +[NOTE] +==== +When working with `java.util.Optional` types, `NullValuePropertyMappingStrategy` applies to empty Optionals in the same way it applies to null values. +An empty `Optional` (i.e., `Optional.isEmpty()` returns `true`) is treated similarly to a `null` value for the purposes of this strategy. For example: + +* With `IGNORE` strategy: an empty `Optional` source property will not update the target property +* With `SET_TO_NULL` strategy: an empty `Optional` source will set the target to `null` (for non-`Optional` targets) or `Optional.empty()` (for Optional targets) +* With `SET_TO_DEFAULT` strategy: an empty `Optional` source will set the target to its default value + +See <> for detailed examples and behavior with Optional types. +==== + +[[checking-source-property-for-null-arguments]] +=== Controlling checking result for 'null' properties in bean mapping + +MapStruct offers control over when to generate a `null` check. By default (`nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION`) a `null` check will be generated for: + +* direct setting of source value to target value when target is primitive and source is not. +* applying type conversion and then: +.. calling the setter on the target. +.. calling another type conversion and subsequently calling the setter on the target. +.. calling a mapping method and subsequently calling the setter on the target. + +First calling a mapping method on the source property is not protected by a null check. Therefore generated mapping methods will do a null check prior to carrying out mapping on a source property. Handwritten mapping methods must take care of null value checking. They have the possibility to add 'meaning' to `null`. For instance: mapping `null` to a default value. + +The option `nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS` will always include a null check when source is non primitive, unless a source presence checker is defined on the source bean. + +The strategy works in a hierarchical fashion. `@Mapping#nullValueCheckStrategy` will override `@BeanMapping#nullValueCheckStrategy`, `@BeanMapping#nullValueCheckStrategy` will override `@Mapper#nullValueCheckStrategy` and `@Mapper#nullValueCheckStrategy` will override `@MapperConfig#nullValueCheckStrategy`. + +[[jspecify-nullness-annotations]] +=== JSpecify nullness annotations + +MapStruct recognises https://jspecify.dev/[JSpecify] nullness annotations on source and target types and uses them to refine when null checks are generated. Only the annotations from `org.jspecify.annotations` are interpreted; MapStruct does not introduce a compile-time dependency on JSpecify, so consumers opt in by adding the dependency themselves. + +The following annotations participate: + +* `@NonNull`: the annotated value is guaranteed not to be `null`. +* `@Nullable`: the annotated value may be `null`. +* `@NullMarked`: within this scope (package, class, or method), unannotated reference types are treated as `@NonNull`. +* `@NullUnmarked`: reverts to unknown nullability within its scope (overrides a `@NullMarked` outer scope). + +==== Property-level rules + +For a single property mapping: + +* If the source is `@NonNull`, the null check is skipped, since the value is treated as guaranteed non-null. +* If the target is `@NonNull` (and the source is not `@NonNull`), a null check is always added so the target's contract is not violated. +* In all other cases, the existing `NullValueCheckStrategy` decides. + +The existing safety guards (`defaultValue` / `defaultExpression`, primitive unboxing, and the relevant `NullValuePropertyMappingStrategy` modes) continue to apply. + +==== Scope: `@NullMarked` and `@NullUnmarked` + +`@NullMarked` and `@NullUnmarked` are resolved by walking from the annotated element outward: method, then declaring class, then outer classes, then package. The closest annotation wins: a `@NullUnmarked` method inside a `@NullMarked` class reverts only that method, while a `@Nullable` annotation on an individual type always overrides the surrounding scope. + +==== Method-level source parameter + +When the source parameter of a mapping method is annotated `@NonNull` (directly or via a `@NullMarked` scope), MapStruct skips the method-level null guard, since the caller is contractually obliged to pass a non-null value. +This rule applies uniformly to bean, iterable, map, and stream mapping methods. + +==== Method-level return type + +When the return type of a mapping method is `@NonNull` (directly or via a `@NullMarked` scope), MapStruct forces `NullValueMappingStrategy.RETURN_DEFAULT` semantics. The generated method returns a default-constructed target (bean methods), an empty collection (`Iterable` / array mappings), an empty map (`Map` mappings), or `Stream.empty()` (stream mappings) rather than `null`, so the return contract is never violated. This rule applies regardless of the explicit `NullValueMappingStrategy` setting. + +==== Constructor parameter constraint + +If a property mapping would assign a potentially `null` source value to a `@NonNull` constructor parameter, MapStruct raises a *compilation error*. Neither inserting a null check (which would leave the variable at `null` and violate the contract) nor passing the value through is safe. Provide a `defaultValue` or `defaultExpression` on the `@Mapping` to satisfy the parameter when the source is absent. + +==== Disabling JSpecify support + +All JSpecify-driven inference can be turned off by setting the processor option `-Amapstruct.disableJSpecify=true`. With the option enabled, MapStruct ignores every JSpecify annotation (`@NonNull`, `@Nullable`, `@NullMarked`, `@NullUnmarked`) and the compilation error for nullable sources mapped to `@NonNull` constructor parameters is not raised. Null-check generation falls back to the pre-JSpecify behavior driven by `NullValueCheckStrategy`. Use this flag when you need to freeze MapStruct's null-handling behavior while JSpecify annotations exist elsewhere on the classpath. + +[[source-presence-check]] +=== Source presence checking +Some frameworks generate bean properties that have a source presence checker. Often this is in the form of a method `hasXYZ`, `XYZ` being a property on the source bean in a bean mapping method. MapStruct will call this `hasXYZ` instead of performing a `null` check when it finds such `hasXYZ` method. + +[TIP] +==== +The source presence checker name can be changed in the MapStruct service provider interface (SPI). It can also be deactivated in this way. +==== + +[NOTE] +==== +Some types of mappings (collections, maps), in which MapStruct is instructed to use a getter or adder as target accessor (see `CollectionMappingStrategy`), MapStruct will always generate a source property +null check, regardless the value of the `NullValueCheckStrategy` to avoid addition of `null` to the target collection or map. +==== + +[[conditional-mapping]] +=== Conditional Mapping + +Conditional Mapping is a type of <>. +The difference is that it allows users to write custom condition methods that will be invoked to check if a property needs to be mapped or not. +Conditional mapping can also be used to check if a source parameter should be mapped or not. + +A custom condition method for properties is a method that is annotated with `org.mapstruct.Condition` and returns `boolean`. +A custom condition method for source parameters is annotated with `org.mapstruct.SourceParameterCondition`, `org.mapstruct.Condition(appliesTo = org.mapstruct.ConditionStrategy#SOURCE_PARAMETERS)` or meta-annotated with `Condition(appliesTo = ConditionStrategy#SOURCE_PARAMETERS)` + +e.g. if you only want to map a String property when it is not `null` and not empty then you can do something like: + +.Mapper using custom condition check method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + CarDto carToCarDto(Car car); + + @Condition + default boolean isNotEmpty(String value) { + return value != null && !value.isEmpty(); + } +} +---- +==== + +The generated mapper will look like: + +.Custom condition check in generated implementation +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CarMapperImpl implements CarMapper { + + @Override + public CarDto carToCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + + if ( isNotEmpty( car.getOwner() ) ) { + carDto.setOwner( car.getOwner() ); + } + + // Mapping of other properties + + return carDto; + } +} +---- +==== + +When using this in combination with an update mapping method it will replace the `null-check` there, for example: + +.Update mapper using custom condition check method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + CarDto carToCarDto(Car car, @MappingTarget CarDto carDto); + + @Condition + default boolean isNotEmpty(String value) { + return value != null && !value.isEmpty(); + } +} +---- +==== + +The generated update mapper will look like: + +.Custom condition check in generated implementation +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CarMapperImpl implements CarMapper { + + @Override + public CarDto carToCarDto(Car car, CarDto carDto) { + if ( car == null ) { + return carDto; + } + + if ( isNotEmpty( car.getOwner() ) ) { + carDto.setOwner( car.getOwner() ); + } else { + carDto.setOwner( null ); + } + + // Mapping of other properties + + return carDto; + } +} +---- +==== + +Additionally `@TargetPropertyName` or `@SourcePropertyName` of type `java.lang.String` can be used in custom condition check method: + +.Mapper using custom condition check method with `@TargetPropertyName` and `@SourcePropertyName` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(target = "owner", source = "ownerName") + CarDto carToCarDto(Car car, @MappingTarget CarDto carDto); + + @Condition + default boolean isNotEmpty( + String value, + @TargetPropertyName String targetPropertyName, + @SourcePropertyName String sourcePropertyName + ) { + + if ( targetPropertyName.equals( "owner" ) + && sourcePropertyName.equals( "ownerName" ) ) { + + return value != null + && !value.isEmpty() + && !value.equals( value.toLowerCase() ); + } + return value != null && !value.isEmpty(); + } +} +---- +==== + +The generated mapper with `@TargetPropertyName` and `@SourcePropertyName` will look like: + +.Custom condition check in generated implementation +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CarMapperImpl implements CarMapper { + + @Override + public CarDto carToCarDto(Car car, CarDto carDto) { + if ( car == null ) { + return carDto; + } + + if ( isNotEmpty( car.getOwner(), "owner", "ownerName" ) ) { + carDto.setOwner( car.getOwner() ); + } else { + carDto.setOwner( null ); + } + + // Mapping of other properties + + return carDto; + } +} +---- +==== + +[IMPORTANT] +==== +If there is a custom `@Condition` method applicable for the property it will have a precedence over a presence check method in the bean itself. +==== + +[NOTE] +==== +Methods annotated with `@Condition` in addition to the value of the source property can also have the source parameter as an input. + +`@TargetPropertyName` and `@SourcePropertyName` parameters can only be used in `@Condition` methods. +==== + +<> is also valid for `@Condition` methods. +In order to use a more specific condition method you will need to use one of `Mapping#conditionQualifiedByName` or `Mapping#conditionQualifiedBy`. + +If we want to only map cars that have an id provided then we can do something like: + + +.Mapper using custom condition source parameter check method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + CarDto carToCarDto(Car car); + + @SourceParameterCondition + default boolean hasCar(Car car) { + return car != null && car.getId() != null; + } +} +---- +==== + +The generated mapper will look like: + +.Custom condition source parameter check generated implementation +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CarMapperImpl implements CarMapper { + + @Override + public CarDto carToCarDto(Car car) { + if ( !hasCar( car ) ) { + return null; + } + + CarDto carDto = new CarDto(); + + carDto.setOwner( car.getOwner() ); + + // Mapping of other properties + + return carDto; + } +} +---- +==== + +[[exceptions]] +=== Exceptions + +Calling applications may require handling of exceptions when calling a mapping method. These exceptions could be thrown by hand-written logic and by the generated built-in mapping methods or type-conversions of MapStruct. When the calling application requires handling of exceptions, a throws clause can be defined in the mapping method: + +.Mapper using custom method declaring checked exception +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(uses = HandWritten.class) +public interface CarMapper { + + CarDto carToCarDto(Car car) throws GearException; +} +---- +==== + +The hand written logic might look like this: + +.Custom mapping method declaring checked exception +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class HandWritten { + + private static final String[] GEAR = {"ONE", "TWO", "THREE", "OVERDRIVE", "REVERSE"}; + + public String toGear(Integer gear) throws GearException, FatalException { + if ( gear == null ) { + throw new FatalException("null is not a valid gear"); + } + + if ( gear < 0 && gear > GEAR.length ) { + throw new GearException("invalid gear"); + } + return GEAR[gear]; + } +} +---- +==== + +MapStruct now, wraps the `FatalException` in a `try-catch` block and rethrows an unchecked `RuntimeException`. MapStruct delegates handling of the `GearException` to the application logic because it is defined as throws clause in the `carToCarDto` method: + +.try-catch block in generated implementation +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +@Override +public CarDto carToCarDto(Car car) throws GearException { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + try { + carDto.setGear( handWritten.toGear( car.getGear() ) ); + } + catch ( FatalException e ) { + throw new RuntimeException( e ); + } + + return carDto; +} +---- +==== + +Some **notes** on null checks. MapStruct does provide null checking only when required: when applying type-conversions or constructing a new type by invoking its constructor. This means that the user is responsible in hand-written code for returning valid non-null objects. Also null objects can be handed to hand-written code, since MapStruct does not want to make assumptions on the meaning assigned by the user to a null object. Hand-written code has to deal with this. diff --git a/documentation/src/main/asciidoc/chapter-11-reusing-mapping-configurations.asciidoc b/documentation/src/main/asciidoc/chapter-11-reusing-mapping-configurations.asciidoc new file mode 100644 index 0000000000..efacaedbe5 --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-11-reusing-mapping-configurations.asciidoc @@ -0,0 +1,167 @@ +== Reusing mapping configurations + +This chapter discusses different means of reusing mapping configurations for several mapping methods: "inheritance" of configuration from other methods and sharing central configuration between multiple mapper types. + +[[mapping-configuration-inheritance]] +=== Mapping configuration inheritance + +Method-level configuration annotations such as `@Mapping`, `@BeanMapping`, `@IterableMapping`, etc., can be *inherited* from one mapping method to a *similar* method using the annotation `@InheritConfiguration`: + +.Update method inheriting its configuration +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(target = "numberOfSeats", source = "seatCount") + Car carDtoToCar(CarDto car); + + @InheritConfiguration + void carDtoIntoCar(CarDto carDto, @MappingTarget Car car); +} +---- +==== + +The example above declares a mapping method `carDtoToCar()` with a configuration to define how the property `numberOfSeats` in the type `Car` shall be mapped. The update method that performs the mapping on an existing instance of `Car` needs the same configuration to successfully map all properties. Declaring `@InheritConfiguration` on the method lets MapStruct search for inheritance candidates to apply the annotations of the method that is inherited from. + +One method *A* can inherit the configuration from another method *B* if all types of *A* (source types and result type) are assignable to the corresponding types of *B*. + +Methods that are considered for inheritance need to be defined in the current mapper, a super class/interface, or in the shared configuration interface (as described in <>). + +In case more than one method is applicable as source for the inheritance, the method name must be specified within the annotation: `@InheritConfiguration( name = "carDtoToCar" )`. + +A method can use `@InheritConfiguration` and override or amend the configuration by additionally applying `@Mapping`, `@BeanMapping`, etc. + +[NOTE] +==== +`@InheritConfiguration` cannot refer to methods in a used mapper. +==== + +[[inverse-mappings]] +=== Inverse mappings + +In case of bi-directional mappings, e.g. from entity to DTO and from DTO to entity, the mapping rules for the forward method and the reverse method are often similar and can simply be inversed by switching `source` and `target`. + +Use the annotation `@InheritInverseConfiguration` to indicate that a method shall inherit the inverse configuration of the corresponding reverse method. + +In the example below, there is no need to write the inverse mapping manually. Think of a case where there are several mappings, so writing the inverse ones can be cumbersome and error prone. + +.Inverse mapping method inheriting its configuration and ignoring some of them +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(target = "seatCount", source = "numberOfSeats") + CarDto carToDto(Car car); + + @InheritInverseConfiguration + @Mapping(target = "numberOfSeats", ignore = true) + Car carDtoToCar(CarDto carDto); +} +---- +==== + +Here the `carDtoToCar()` method is the reverse mapping method for `carToDto()`. Note that any attribute mappings from `carToDto()` will be applied to the corresponding reverse mapping method as well. They are automatically reversed and copied to the method with the `@InheritInverseConfiguration` annotation. + +Specific mappings from the inversed method can (optionally) be overridden by `ignore`, `expression` or `constant` in the mapping, e.g. like this: `@Mapping(target = "numberOfSeats", ignore=true)`. + +A method *A* is considered a *reverse* method of a method *B*, if the result type of *A* is the *same* as the single source type of *B* and if the single source type of *A* is the *same* as the result type of *B*. + +Methods that are considered for inverse inheritance need to be defined in the current mapper, a super class/interface. + +If multiple methods qualify, the method from which to inherit the configuration needs to be specified using the `name` property like this: `@InheritInverseConfiguration(name = "carToDto")`. + +`@InheritConfiguration` takes, in case of conflict precedence over `@InheritInverseConfiguration`. + +Configurations are inherited transitively. So if method `C` defines a mapping `@Mapping( target = "x", ignore = true)`, `B` defines a mapping `@Mapping( target = "y", ignore = true)`, then if `A` inherits from `B` inherits from `C`, `A` will inherit mappings for both property `x` and `y`. + +`@Mapping#expression`, `@Mapping#defaultExpression`, `@Mapping#defaultValue` and `@Mapping#constant` are excluded (silently ignored) in `@InheritInverseConfiguration`. + +`@Mapping#ignore` is only applied when `@Mapping#source` is also present in `@InheritInverseConfiguration`. + +Reverse mapping of nested source properties is experimental as of the 1.1.0.Beta2 release. Reverse mapping will take place automatically when the source property name and target property name are identical. Otherwise, `@Mapping` should specify both the target name and source name. In all cases, a suitable mapping method needs to be in place for the reverse mapping. + +[NOTE] +==== +`@InheritInverseConfiguration` cannot refer to methods in a used mapper. +==== + +[[shared-configurations]] +=== Shared configurations + +MapStruct offers the possibility to define a shared configuration by pointing to a central interface annotated with `@MapperConfig`. For a mapper to use the shared configuration, the configuration interface needs to be defined in the `@Mapper#config` property. + +The `@MapperConfig` annotation has the same attributes as the `@Mapper` annotation. Any attributes not given via `@Mapper` will be inherited from the shared configuration. Attributes specified in `@Mapper` take precedence over the attributes specified via the referenced configuration class. List properties such as `uses` are simply combined: + +.Mapper configuration class and mapper using it +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@MapperConfig( + uses = CustomMapperViaMapperConfig.class, + unmappedTargetPolicy = ReportingPolicy.ERROR +) +public interface CentralConfig { +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(config = CentralConfig.class, uses = { CustomMapperViaMapper.class } ) +// Effective configuration: +// @Mapper( +// uses = { CustomMapperViaMapper.class, CustomMapperViaMapperConfig.class }, +// unmappedTargetPolicy = ReportingPolicy.ERROR +// ) +public interface SourceTargetMapper { + ... +} + +---- +==== + +The interface holding the `@MapperConfig` annotation may also declare *prototypes* of mapping methods that can be used to inherit method-level mapping annotations from. Such prototype methods are not meant to be implemented or used as part of the mapper API. + +.Mapper configuration class with prototype methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@MapperConfig( + uses = CustomMapperViaMapperConfig.class, + unmappedTargetPolicy = ReportingPolicy.ERROR, + mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG +) +public interface CentralConfig { + + // Not intended to be generated, but to carry inheritable mapping annotations: + @Mapping(target = "primaryKey", source = "technicalKey") + BaseEntity anyDtoToEntity(BaseDto dto); +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(config = CentralConfig.class, uses = { CustomMapperViaMapper.class } ) +public interface SourceTargetMapper { + + @Mapping(target = "numberOfSeats", source = "seatCount") + // additionally inherited from CentralConfig, because Car extends BaseEntity and CarDto extends BaseDto: + // @Mapping(target = "primaryKey", source = "technicalKey") + Car toCar(CarDto car) +} +---- +==== + +The attributes `@Mapper#mappingInheritanceStrategy()` / `@MapperConfig#mappingInheritanceStrategy()` configure when the method-level mapping configuration annotations are inherited from prototype methods in the interface to methods in the mapper: + +* `EXPLICIT` (default): the configuration will only be inherited, if the target mapping method is annotated with `@InheritConfiguration` and the source and target types are assignable to the corresponding types of the prototype method, all as described in <>. +* `AUTO_INHERIT_FROM_CONFIG`: the configuration will be inherited automatically, if the source and target types of the target mapping method are assignable to the corresponding types of the prototype method. If multiple prototype methods match, the ambiguity must be resolved using `@InheritConfiguration(name = ...)` which will cause `AUTO_INHERIT_FROM_CONFIG` to be ignored. +* `AUTO_INHERIT_REVERSE_FROM_CONFIG`: the inverse configuration will be inherited automatically, if the source and target types of the target mapping method are assignable to the corresponding types of the prototype method. If multiple prototype methods match, the ambiguity must be resolved using `@InheritInverseConfiguration(name = ...)` which will cause ``AUTO_INHERIT_REVERSE_FROM_CONFIG` to be ignored. +* `AUTO_INHERIT_ALL_FROM_CONFIG`: both the configuration and the inverse configuration will be inherited automatically. The same rules apply as for `AUTO_INHERIT_FROM_CONFIG` or `AUTO_INHERIT_REVERSE_FROM_CONFIG`. diff --git a/documentation/src/main/asciidoc/chapter-12-customizing-mapping.asciidoc b/documentation/src/main/asciidoc/chapter-12-customizing-mapping.asciidoc new file mode 100644 index 0000000000..dc07b30e62 --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-12-customizing-mapping.asciidoc @@ -0,0 +1,271 @@ +== Customizing mappings + +Sometimes it's needed to apply custom logic before or after certain mapping methods. MapStruct provides two ways for doing so: decorators which allow for a type-safe customization of specific mapping methods and the before-mapping and after-mapping lifecycle methods which allow for a generic customization of mapping methods with given source or target types. + +[[customizing-mappers-using-decorators]] +=== Mapping customization with decorators + +In certain cases it may be required to customize a generated mapping method, e.g. to set an additional property in the target object which can't be set by a generated method implementation. MapStruct supports this requirement using decorators. + +[TIP] +When working with the component model `cdi`, use https://docs.jboss.org/cdi/spec/1.0/html/decorators.html[CDI decorators] with MapStruct mappers instead of the `@DecoratedWith` annotation described here. + +To apply a decorator to a mapper class, specify it using the `@DecoratedWith` annotation. + +.Applying a decorator +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +@DecoratedWith(PersonMapperDecorator.class) +public interface PersonMapper { + + PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class ); + + PersonDto personToPersonDto(Person person); + + AddressDto addressToAddressDto(Address address); +} +---- +==== + +The decorator must be a sub-type of the decorated mapper type. You can make it an abstract class which allows to only implement those methods of the mapper interface which you want to customize. For all non-implemented methods, a simple delegation to the original mapper will be generated using the default generation routine. + +The `PersonMapperDecorator` shown below customizes the `personToPersonDto()`. It sets an additional attribute which is not present in the source type of the mapping. The `addressToAddressDto()` method is not customized. + +.Implementing a decorator +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public abstract class PersonMapperDecorator implements PersonMapper { + + private final PersonMapper delegate; + + public PersonMapperDecorator(PersonMapper delegate) { + this.delegate = delegate; + } + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setFullName( person.getFirstName() + " " + person.getLastName() ); + return dto; + } +} +---- +==== + +The example shows how you can optionally inject a delegate with the generated default implementation and use this delegate in your customized decorator methods. + +For a mapper with `componentModel = "default"`, define a constructor with a single parameter which accepts the type of the decorated mapper. + +When working with the component models `spring` or `jsr330`, this needs to be handled differently. + +[[decorators-with-spring]] +==== Decorators with the Spring component model + +When using `@DecoratedWith` on a mapper with component model `spring`, the generated implementation of the original mapper is annotated with the Spring annotation `@Qualifier("delegate")`. To autowire that bean in your decorator, add that qualifier annotation as well: + +.Spring-based decorator +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public abstract class PersonMapperDecorator implements PersonMapper { + + @Autowired + @Qualifier("delegate") + private PersonMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + + return dto; + } + } +---- +==== + +The generated class that extends the decorator is annotated with Spring's `@Primary` annotation. To autowire the decorated mapper in the application, nothing special needs to be done: + +.Using a decorated mapper +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Autowired +private PersonMapper personMapper; // injects the decorator, with the injected original mapper +---- +==== + +[[decorators-with-jsr-330]] +==== Decorators with the JSR 330 component model + +JSR 330 doesn't specify qualifiers and only allows to specifically name the beans. Hence, the generated implementation of the original mapper is annotated with `@Named("fully-qualified-name-of-generated-implementation")` (please note that when using a decorator, the class name of the mapper implementation ends with an underscore). To inject that bean in your decorator, add the same annotation to the delegate field (e.g. by copy/pasting it from the generated class): + +.JSR 330 based decorator +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public abstract class PersonMapperDecorator implements PersonMapper { + + @Inject + @Named("org.examples.PersonMapperImpl_") + private PersonMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + + return dto; + } +} +---- +==== + +Unlike with the other component models, the usage site must be aware if a mapper is decorated or not, as for decorated mappers, the parameterless `@Named` annotation must be added to select the decorator to be injected: + +.Using a decorated mapper with JSR 330 +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Inject +@Named +private PersonMapper personMapper; // injects the decorator, with the injected original mapper +---- +==== + +[[customizing-mappings-with-before-and-after]] +=== Mapping customization with before-mapping and after-mapping methods + +Decorators may not always fit the needs when it comes to customizing mappers. For example, if you need to perform the customization not only for a few selected methods, but for all methods that map specific super-types: in that case, you can use *callback methods* that are invoked before the mapping starts or after the mapping finished. + +Callback methods can be implemented in the abstract mapper itself, in a type reference in `Mapper#uses`, or in a type used as `@Context` parameter. + +.Mapper with @BeforeMapping and @AfterMapping hooks +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public abstract class VehicleMapper { + + @BeforeMapping + protected void flushEntity(AbstractVehicle vehicle) { + // I would call my entity manager's flush() method here to make sure my entity + // is populated with the right @Version before I let it map into the DTO + } + + @AfterMapping + protected void fillTank(AbstractVehicle vehicle, @MappingTarget AbstractVehicleDto result) { + result.fuelUp( new Fuel( vehicle.getTankCapacity(), vehicle.getFuelType() ) ); + } + + public abstract CarDto toCarDto(Car car); +} + +// Generates something like this: +public class VehicleMapperImpl extends VehicleMapper { + + public CarDto toCarDto(Car car) { + flushEntity( car ); + + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + // attributes mapping ... + + fillTank( car, carDto ); + + return carDto; + } +} +---- +==== + +If the `@BeforeMapping` / `@AfterMapping` method has parameters, the method invocation is only generated if the return type of the method (if non-`void`) is assignable to the return type of the mapping method and all parameters can be *assigned* by the source or target parameters of the mapping method: + +* A parameter annotated with `@MappingTarget` is populated with the target instance of the mapping. +* A parameter annotated with `@TargetType` is populated with the target type of the mapping. +* Parameters annotated with `@Context` are populated with the context parameters of the mapping method. +* Any other parameter is populated with a source parameter of the mapping. + +For non-`void` methods, the return value of the method invocation is returned as the result of the mapping method if it is not `null`. + +As with mapping methods, it is possible to specify type parameters for before/after-mapping methods. + +.Mapper with @AfterMapping hook that returns a non-null value +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public abstract class VehicleMapper { + + @PersistenceContext + private EntityManager entityManager; + + @AfterMapping + protected T attachEntity(@MappingTarget T entity) { + return entityManager.merge(entity); + } + + public abstract CarDto toCarDto(Car car); +} + +// Generates something like this: +public class VehicleMapperImpl extends VehicleMapper { + + public CarDto toCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + // attributes mapping ... + + CarDto target = attachEntity( carDto ); + if ( target != null ) { + return target; + } + + return carDto; + } +} +---- +==== + +All before/after-mapping methods that *can* be applied to a mapping method *will* be used. <> can be used to further control which methods may be chosen and which not. For that, the qualifier annotation needs to be applied to the before/after-method and referenced in `BeanMapping#qualifiedBy` or `IterableMapping#qualifiedBy`. + +The order of the method invocation is determined primarily by their variant: + +1. `@BeforeMapping` methods without parameters, a `@MappingTarget` parameter or a `@TargetType` parameter are called before any null-checks on source parameters and constructing a new target bean. +2. `@BeforeMapping` methods with a `@MappingTarget` parameter are called after constructing a new target bean. +3. `@AfterMapping` methods are called at the end of the mapping method before the last `return` statement. + +Within those groups, the method invocations are ordered by their location of definition: + +1. Methods declared on `@Context` parameters, ordered by the parameter order. +2. Methods implemented in the mapper itself. +3. Methods from types referenced in `Mapper#uses()`, in the order of the type declaration in the annotation. +4. Methods declared in one type are used after methods declared in their super-type. + +*Important:* the order of methods declared within one type can not be guaranteed, as it depends on the compiler and the processing environment implementation. + +[NOTE] +==== +Before/After-mapping methods can also be used with builders: + +* `@BeforeMapping` methods with a `@MappingTarget` parameter of the real target will not be invoked because it is only available after the mapping was already performed. +* To be able to modify the object that is going to be built, the `@AfterMapping` annotated method must have the builder as `@MappingTarget` annotated parameter. The `build` method is called when the `@AfterMapping` annotated method scope finishes. +* The `@AfterMapping` annotated method can also have the real target as `@TargetType` or `@MappingTarget`. It will be invoked after the real target was built (first the methods annotated with `@TargetType`, then the methods annotated with `@MappingTarget`) +==== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc b/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc new file mode 100644 index 0000000000..51b2bbff3c --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-13-using-mapstruct-spi.asciidoc @@ -0,0 +1,424 @@ +[[using-spi]] +== Using the MapStruct SPI + +To use a custom SPI implementation, it must be located in a separate JAR file together with a file named after the SPI (e.g. `org.mapstruct.ap.spi.AccessorNamingStrategy`) in `META-INF/services/` with the fully qualified name of your custom implementation as content (e.g. `org.mapstruct.example.CustomAccessorNamingStrategy`). This JAR file needs to be added to the annotation processor classpath (i.e. add it next to the place where you added the mapstruct-processor jar). + + +[NOTE] +==== +It might also be necessary to add the jar to your IDE's annotation processor factory path. Otherwise you might get an error stating that it cannot be found, while a run using your build tool does succeed. +==== + +=== Custom Accessor Naming Strategy + +SPI name: `org.mapstruct.ap.spi.AccessorNamingStrategy` + +MapStruct offers the possibility to override the `AccessorNamingStrategy` via the Service Provider Interface (SPI). A nice example is the use of the fluent API on the source object `GolfPlayer` and `GolfPlayerDto` below. + +.Source object GolfPlayer with fluent API. +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class GolfPlayer { + + private double handicap; + private String name; + + public double handicap() { + return handicap; + } + + public GolfPlayer withHandicap(double handicap) { + this.handicap = handicap; + return this; + } + + public String name() { + return name; + } + + public GolfPlayer withName(String name) { + this.name = name; + return this; + } +} +---- +==== + +.Source object GolfPlayerDto with fluent API. +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class GolfPlayerDto { + + private double handicap; + private String name; + + public double handicap() { + return handicap; + } + + public GolfPlayerDto withHandicap(double handicap) { + this.handicap = handicap; + return this; + } + + public String name() { + return name; + } + + public GolfPlayerDto withName(String name) { + this.name = name; + return this; + } +} +---- +==== + +We want `GolfPlayer` to be mapped to a target object `GolfPlayerDto` similar like we 'always' do this: + +.Source object with fluent API. +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface GolfPlayerMapper { + + GolfPlayerMapper INSTANCE = Mappers.getMapper( GolfPlayerMapper.class ); + + GolfPlayerDto toDto(GolfPlayer player); + + GolfPlayer toPlayer(GolfPlayerDto player); + +} +---- +==== + +This can be achieved with implementing the SPI `org.mapstruct.ap.spi.AccessorNamingStrategy` as in the following example. Here's an implemented `org.mapstruct.ap.spi.AccessorNamingStrategy`: + +.CustomAccessorNamingStrategy +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +/** + * A custom {@link AccessorNamingStrategy} recognizing getters in the form of {@code property()} and setters in the + * form of {@code withProperty(value)}. + */ +public class CustomAccessorNamingStrategy extends DefaultAccessorNamingStrategy { + + @Override + public boolean isGetterMethod(ExecutableElement method) { + String methodName = method.getSimpleName().toString(); + return !methodName.startsWith( "with" ) && method.getReturnType().getKind() != TypeKind.VOID; + } + + @Override + public boolean isSetterMethod(ExecutableElement method) { + String methodName = method.getSimpleName().toString(); + return methodName.startsWith( "with" ) && methodName.length() > 4; + } + + @Override + public String getPropertyName(ExecutableElement getterOrSetterMethod) { + String methodName = getterOrSetterMethod.getSimpleName().toString(); + return IntrospectorUtils.decapitalize( methodName.startsWith( "with" ) ? methodName.substring( 4 ) : methodName ); + } +} +---- +==== +The `CustomAccessorNamingStrategy` makes use of the `DefaultAccessorNamingStrategy` (also available in mapstruct-processor) and relies on that class to leave most of the default behaviour unchanged. + +[TIP] +Fore more details: The example above is present in our examples repository (https://github.com/mapstruct/mapstruct-examples). + +[[mapping-exclusion-provider]] +=== Mapping Exclusion Provider + +SPI name: `org.mapstruct.ap.spi.MappingExclusionProvider` + +MapStruct offers the possibility to override the `MappingExclusionProvider` via the Service Provider Interface (SPI). +A nice example is to not allow MapStruct to create an automatic sub-mapping for a certain type, +i.e. MapStruct will not try to generate an automatic sub-mapping method for an excluded type. + +[NOTE] +==== +The `DefaultMappingExclusionProvider` will exclude all types under the `java` or `javax` packages. +This means that MapStruct will not try to generate an automatic sub-mapping method between some custom type and some type declared in the Java class library. +==== + +.Source object +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/nestedbeans/exclusions/custom/Source.java[tag=documentation] +---- +==== + +.Target object +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/nestedbeans/exclusions/custom/Target.java[tag=documentation] +---- +==== + +.Mapper definition +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/nestedbeans/exclusions/custom/ErroneousCustomExclusionMapper.java[tag=documentation] +---- +==== + +We want to exclude the `NestedTarget` from the automatic sub-mapping method generation. + +.CustomMappingExclusionProvider +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/nestedbeans/exclusions/custom/CustomMappingExclusionProvider.java[tag=documentation] +---- +==== + + +[[custom-builder-provider]] +=== Custom Builder Provider + +SPI name: org.mapstruct.ap.spi.BuilderProvider + +MapStruct offers the possibility to override the `DefaultProvider` via the Service Provider Interface (SPI). +A nice example is to provide support for a custom builder strategy. + +.Custom Builder Provider which disables Builder support +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-main}/spi/NoOpBuilderProvider.java[tag=documentation] +---- +==== + +[[custom-enum-naming-strategy]] +=== Custom Enum Naming Strategy + +SPI name: `org.mapstruct.ap.spi.EnumMappingStrategy` + +MapStruct offers the possibility to override the `EnumMappingStrategy` via the Service Provider Interface (SPI). +This can be used when you have certain enums that follow some conventions within your organization. +For example all enums which implement an interface named `CustomEnumMarker` are prefixed with `CUSTOM_` +and the default value for them when mapping from `null` is `UNSPECIFIED` + +.Normal Enum +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public enum CheeseType { + BRIE, + ROQUEFORT; +} +---- +==== + +.Custom marker enum +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public enum CustomCheeseType implements CustomEnumMarker { + + UNSPECIFIED, + CUSTOM_BRIE, + CUSTOM_ROQUEFORT; +} +---- +==== + +We want `CheeseType` and `CustomCheeseType` to be mapped without the need to manually define the value mappings: + +.Custom enum mapping +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CheeseTypeMapper { + + CheeseType map(CustomCheeseType cheese); + + CustomCheeseType map(CheeseType cheese); +} +---- +==== + +This can be achieved with implementing the SPI `org.mapstruct.ap.spi.EnumMappingStrategy` as in the following example. +Here’s an implemented `org.mapstruct.ap.spi.EnumMappingStrategy`: + +.Custom enum naming strategy +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class CustomEnumMappingStrategy extends DefaultEnumMappingStrategy { + + @Override + public String getDefaultNullEnumConstant(TypeElement enumType) { + if ( isCustomEnum( enumType ) ) { + return "UNSPECIFIED"; + } + + return super.getDefaultNullEnumConstant( enumType ); + } + + @Override + public String getEnumConstant(TypeElement enumType, String enumConstant) { + if ( isCustomEnum( enumType ) ) { + return getCustomEnumConstant( enumConstant ); + } + return super.getEnumConstant( enumType, enumConstant ); + } + protected String getCustomEnumConstant(String enumConstant) { + if ( "UNSPECIFIED".equals( enumConstant ) ) { + return MappingConstantsGem.NULL; + } + return enumConstant.replace( "CUSTOM_", "" ); + } + protected boolean isCustomEnum(TypeElement enumType) { + for ( TypeMirror enumTypeInterface : enumType.getInterfaces() ) { + if ( typeUtils.asElement( enumTypeInterface ).getSimpleName().contentEquals( "CustomEnumMarker" ) ) { + return true; + } + } + return false; + } +} +---- +==== + +The generated code then for the `CheeseMapper` looks like: + +.Generated CheeseTypeMapper +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class CheeseTypeMapperImpl implements CheeseTypeMapper { + + @Override + public CheeseType map(CustomCheeseType cheese) { + if ( cheese == null ) { + return null; + } + + CheeseType cheeseType; + + switch ( cheese ) { + case UNRECOGNIZED: cheeseType = null; + break; + case CUSTOM_BRIE: cheeseType = CheeseType.BRIE; + break; + case CUSTOM_ROQUEFORT: cheeseType = CheeseType.ROQUEFORT; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheese ); + } + + return cheeseType; + } + + @Override + public CustomCheeseType map(CheeseType cheese) { + if ( cheese == null ) { + return CustomCheeseType.UNSPECIFIED; + } + + CustomCheeseType customCheeseType; + + switch ( cheese ) { + case BRIE: customCheeseType = CustomCheeseType.CUSTOM_BRIE; + break; + case ROQUEFORT: customCheeseType = CustomCheeseType.CUSTOM_ROQUEFORT; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheese ); + } + + return customCheeseType; + } +} +---- +==== + +[[custom-enum-transformation-strategy]] +=== Custom Enum Transformation Strategy + +SPI name: `org.mapstruct.ap.spi.EnumTransformationStrategy` + +MapStruct offers the possibility to other transformations strategies by implementing `EnumTransformationStrategy` via the Service Provider Interface (SPI). +A nice example is to provide support for a custom transformation strategy. + +.Custom Enum Transformation Strategy which lower-cases the value and applies a suffix +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/value/nametransformation/CustomEnumTransformationStrategy.java[tag=documentation] +---- +==== + +[[additional-supported-options-provider]] +=== Additional Supported Options Provider + +SPI name: `org.mapstruct.ap.spi.AdditionalSupportedOptionsProvider` + +MapStruct offers the ability to pass through declared compiler args (or "options") provided to the MappingProcessor +to the individual SPIs, by implementing `AdditionalSupportedOptionsProvider` via the Service Provider Interface (SPI). + +.Custom Additional Supported Options Provider that declares `myorg.custom.defaultNullEnumConstant` as an option to pass through +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/additionalsupportedoptions/CustomAdditionalSupportedOptionsProvider.java[tag=documentation] +---- +==== + +The value of this option is provided by including an `arg` to the `compilerArgs` tag when defining your custom SPI +implementation. + +.Example maven configuration with additional options +==== +[source, maven, linenums] +[subs="verbatim,attributes"] +---- + + + + org.myorg + custom-spi-impl + ${project.version} + + + + -Amyorg.custom.defaultNullEnumConstant=MISSING + + +---- +==== + +Your custom SPI implementations can then access this configured value via `MapStructProcessingEnvironment#getOptions()`. + +.Accessing your custom options +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +include::{processor-ap-test}/additionalsupportedoptions/UnknownEnumMappingStrategy.java[tag=documentation] +---- +==== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/chapter-14-third-party-api-integration.asciidoc b/documentation/src/main/asciidoc/chapter-14-third-party-api-integration.asciidoc new file mode 100644 index 0000000000..ef2a58f82e --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-14-third-party-api-integration.asciidoc @@ -0,0 +1,192 @@ +[[third-party-api-integration]] +== Third-party API integration + +[[non-shipped-annotations]] +=== Non-shipped annotations + +There are various use-cases you must resolve ambiguity for MapStruct to use a correct piece of code. +However, the primary goal of MapStruct is to focus on bean mapping without polluting the entity code. +For that reason, MapStruct is flexible enough to interact with already defined annotations from third-party libraries. +The requirement to enable this behavior is to match the _name_ of such annotation. +Hence, we say that annotation can be _from any package_. + +The annotations _named_ `@ConstructorProperties` and `@Default` are currently examples of this kind of annotation. + +[WARNING] +==== +If such named third-party annotation exists, it does not guarantee its `@Target` matches with the intended placement. +Be aware of placing a third-party annotation just for sake of mapping is not recommended as long as it might lead to unwanted side effects caused by that library. +==== + +A very common case is that no third-party dependency imported to your project provides such annotation or is inappropriate for use as already described. +In such cases create your own annotation, for example: + +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +package foo.support.mapstruct; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.CONSTRUCTOR) +@Retention(RetentionPolicy.CLASS) +public @interface Default { + +} +---- +==== + +[[lombok]] +=== Lombok + +MapStruct works together with https://projectlombok.org/[Project Lombok] as of MapStruct 1.2.0.Beta1 and Lombok 1.16.14. + +MapStruct takes advantage of generated getters, setters, and constructors and uses them to generate the mapper implementations. +Be reminded that the generated code by Lombok might not always be compatible with the expectations from the individual mappings. +In such a case, either Mapstruct mapping must be changed or Lombok must be configured accordingly using https://projectlombok.org/features/configuration[`lombok.config`] for mutual synergy. + +[WARNING] +==== +Lombok 1.18.16 introduces a breaking change (https://projectlombok.org/changelog[changelog]). +The additional annotation processor `lombok-mapstruct-binding` (https://mvnrepository.com/artifact/org.projectlombok/lombok-mapstruct-binding[Maven]) must be added otherwise MapStruct stops working with Lombok. +This resolves the compilation issues of Lombok and MapStruct modules. + +[source, xml] +---- + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + +---- +==== + +==== Set up + +The set up using Maven or Gradle does not differ from what is described in <>. Additionally, you need to provide Lombok dependencies. + +.Maven configuration +==== +[source, xml, linenums] +[subs="verbatim,attributes"] +---- + + + {mapstructVersion} + 1.18.16 + 1.8 + 1.8 + + + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + + + + org.projectlombok + lombok + ${org.projectlombok.version} + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + org.projectlombok + lombok + ${org.projectlombok.version} + + + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + + + +---- +==== + +.Gradle configuration (3.4 and later) +==== +[source, groovy, linenums] +[subs="verbatim,attributes"] +---- + +dependencies { + + implementation "org.mapstruct:mapstruct:${mapstructVersion}" + compileOnly "org.projectlombok:lombok:1.18.16" + annotationProcessor "org.projectlombok:lombok-mapstruct-binding:0.2.0" + annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" + annotationProcessor "org.projectlombok:lombok:1.18.16" +} + +---- +==== + +The usage combines what you already know from <> and Lombok. + +.Usage of MapStruct with Lombok +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Data +public class Source { + + private String test; +} + +public class Target { + + private Long testing; + + public Long getTesting() { + return testing; + } + + public void setTesting( Long testing ) { + this.testing = testing; + } +} + +@Mapper +public interface SourceTargetMapper { + + SourceTargetMapper MAPPER = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping( source = "test", target = "testing" ) + Target toTarget( Source s ); +} + +---- +==== + +A working example can be found on the GitHub project https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-lombok[mapstruct-lombok]. diff --git a/documentation/src/main/asciidoc/chapter-2-set-up.asciidoc b/documentation/src/main/asciidoc/chapter-2-set-up.asciidoc new file mode 100644 index 0000000000..31479f8a20 --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-2-set-up.asciidoc @@ -0,0 +1,389 @@ +[[setup]] +== Set up + +MapStruct is a Java annotation processor based on http://www.jcp.org/en/jsr/detail?id=269[JSR 269] and as such can be used within command line builds (javac, Ant, Maven etc.) as well as from within your IDE. + +It comprises the following artifacts: + +* _org.mapstruct:mapstruct_: contains the required annotations such as `@Mapping` +* _org.mapstruct:mapstruct-processor_: contains the annotation processor which generates mapper implementations + +=== Apache Maven + +For Maven based projects add the following to your POM file in order to use MapStruct: + +.Maven configuration +==== +[source, xml, linenums] +[subs="verbatim,attributes"] +---- +... + + {mapstructVersion} + +... + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + +... + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.14.1 + + ${java.version} + ${java.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + + + +... +---- +==== + +[TIP] +==== +If you are working with the Eclipse IDE, make sure to have a current version of the http://www.eclipse.org/m2e/[M2E plug-in]. +When importing a Maven project configured as shown above, it will set up the MapStruct annotation processor so it runs right in the IDE, whenever you save a mapper type. +Neat, isn't it? + +To double check that everything is working as expected, go to your project's properties and select "Java Compiler" -> "Annotation Processing" -> "Factory Path". +The MapStruct processor JAR should be listed and enabled there. +Any processor options configured via the compiler plug-in (see below) should be listed under "Java Compiler" -> "Annotation Processing". + +If the processor is not kicking in, check that the configuration of annotation processors through M2E is enabled. +To do so, go to "Preferences" -> "Maven" -> "Annotation Processing" and select "Automatically configure JDT APT". +Alternatively, specify the following in the `properties` section of your POM file: `jdt_apt`. + +Also make sure that your project is using Java 1.8 or later (project properties -> "Java Compiler" -> "Compile Compliance Level"). +It will not work with older versions. +==== + +=== Gradle + +Add the following to your Gradle build file in order to enable MapStruct: + +.Gradle configuration +==== +[source, groovy, linenums] +[subs="verbatim,attributes"] +---- +... +plugins { + ... + id "com.diffplug.eclipse.apt" version "3.26.0" // Only for Eclipse +} + +dependencies { + ... + implementation "org.mapstruct:mapstruct:${mapstructVersion}" + annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" + + // If you are using mapstruct in test code + testAnnotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" +} +... +---- +==== + +You can find a complete example in the https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-on-gradle[mapstruct-examples] project on GitHub. + + +=== Apache Ant + +Add the `javac` task configured as follows to your _build.xml_ file in order to enable MapStruct in your Ant-based project. Adjust the paths as required for your project layout. + +.Ant configuration +==== +[source, xml, linenums] +[subs="verbatim,attributes"] +---- +... + + + + +... +---- +==== + +You can find a complete example in the https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-on-ant[mapstruct-examples] project on GitHub. + +[[configuration-options]] +=== Configuration options + +The MapStruct code generator can be configured using _annotation processor options_. + +When invoking javac directly, these options are passed to the compiler in the form _-Akey=value_. When using MapStruct via Maven, any processor options can be passed using `compilerArgs` within the configuration of the Maven processor plug-in like this: + +.Maven configuration +==== +[source, xml, linenums] +[subs="verbatim,attributes"] +---- +... + + org.apache.maven.plugins + maven-compiler-plugin + 3.14.1 + + ${java.version} + ${java.version} + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + + true + + + -Amapstruct.suppressGeneratorTimestamp=true + + + -Amapstruct.suppressGeneratorVersionInfoComment=true + + + -Amapstruct.verbose=true + + + + +... +---- +==== + +.Gradle configuration +==== +[source, groovy, linenums] +[subs="verbatim,attributes"] +---- +... +compileJava { + options.compilerArgs += [ + '-Amapstruct.suppressGeneratorTimestamp=true', + '-Amapstruct.suppressGeneratorVersionInfoComment=true', + '-Amapstruct.verbose=true' + ] +} +... +---- +==== + +The following options exist: + +.MapStruct processor options +[cols="1,2a,1"] +|=== +|Option|Purpose|Default + +|`mapstruct. +suppressGeneratorTimestamp` +|If set to `true`, the creation of a time stamp in the `@Generated` annotation in the generated mapper classes is suppressed. +|`false` + +|`mapstruct.verbose` +|If set to `true`, MapStruct in which MapStruct logs its major decisions. Note, at the moment of writing in Maven, also `showWarnings` needs to be added due to a problem in the maven-compiler-plugin configuration. +|`false` + +|`mapstruct. +suppressGeneratorVersionInfoComment` +|If set to `true`, the creation of the `comment` attribute in the `@Generated` annotation in the generated mapper classes is suppressed. The comment contains information about the version of MapStruct and about the compiler used for the annotation processing. +|`false` + +|`mapstruct.defaultComponentModel` +|The name of the component model (see <>) based on which mappers should be generated. + +Supported values are: + +* `default`: the mapper uses no component model, instances are typically retrieved via `Mappers#getMapper(Class)` +* `cdi`: the generated mapper is an application-scoped (from javax.enterprise.context or jakarta.enterprise.context, depending on which one is available with javax.inject having priority) CDI bean and can be retrieved via `@Inject` +* `spring`: the generated mapper is a singleton-scoped Spring bean and can be retrieved via `@Autowired` +* `jsr330`: the generated mapper is annotated with {@code @Named} and can be retrieved via `@Inject` (from javax.inject or jakarta.inject, depending which one is available with javax.inject having priority), e.g. using Spring +* `jakarta`: the generated mapper is annotated with {@code @Named} and can be retrieved via `@Inject` (from jakarta.inject), e.g. using Spring +* `jakarta-cdi`: the generated mapper is an application-scoped (from jakarta.enterprise.context) CDI bean and can be retrieved via `@Inject` + +If a component model is given for a specific mapper via `@Mapper#componentModel()`, the value from the annotation takes precedence. +|`default` + +|`mapstruct.defaultInjectionStrategy` +| The type of the injection in mapper via parameter `uses`. This is only used on annotated based component models + such as CDI, Spring and JSR 330. + +Supported values are: + +* `field`: dependencies will be injected in fields +* `constructor`: will be generated constructor. Dependencies will be injected via constructor. + +When CDI `componentModel` a default constructor will also be generated. +If a injection strategy is given for a specific mapper via `@Mapper#injectionStrategy()`, the value from the annotation takes precedence over the option. +|`field` + +|`mapstruct.unmappedTargetPolicy` +|The default reporting policy to be applied in case an attribute of the target object of a mapping method is not populated with a source value. + +Supported values are: + +* `ERROR`: any unmapped target property will cause the mapping code generation to fail +* `WARN`: any unmapped target property will cause a warning at build time +* `IGNORE`: unmapped target properties are ignored + +If a policy is given for a specific mapper via `@Mapper#unmappedTargetPolicy()`, the value from the annotation takes precedence. +If a policy is given for a specific bean mapping via `@BeanMapping#unmappedTargetPolicy()`, it takes precedence over both `@Mapper#unmappedTargetPolicy()` and the option. +|`WARN` + +|`mapstruct.unmappedSourcePolicy` +|The default reporting policy to be applied in case an attribute of the source object of a mapping method is not populated with a target value. + +Supported values are: + +* `ERROR`: any unmapped source property will cause the mapping code generation to fail +* `WARN`: any unmapped source property will cause a warning at build time +* `IGNORE`: unmapped source properties are ignored + +If a policy is given for a specific mapper via `@Mapper#unmappedSourcePolicy()`, the value from the annotation takes precedence. +If a policy is given for a specific bean mapping via `@BeanMapping#ignoreUnmappedSourceProperties()`, it takes precedence over both `@Mapper#unmappedSourcePolicy()` and the option. +|`IGNORE` + +|`mapstruct. +disableBuilders` +|If set to `true`, then MapStruct will not use builder patterns when doing the mapping. This is equivalent to doing `@Mapper( builder = @Builder( disableBuilder = true ) )` for all of your mappers. +|`false` + +|`mapstruct. +disableJSpecify` +|If set to `true`, MapStruct ignores all JSpecify nullness annotations (`@NonNull`, `@Nullable`, `@NullMarked`, `@NullUnmarked`) when deciding whether to generate null checks and does not raise the compilation error for a nullable source mapped to a `@NonNull` constructor parameter. Null-check generation falls back to the `NullValueCheckStrategy`-driven behavior. +|`false` + +|`mapstruct.nullValueIterableMappingStrategy` +|The strategy to be applied when `null` is passed as a source value to an iterable mapping. + +Supported values are: + +* `RETURN_NULL`: if `null` is passed as a source value, then `null` will be returned +* `RETURN_DEFAULT`: if `null` is passed then a default value (empty collection) will be returned + +If a strategy is given for a specific mapper via `@Mapper#nullValueIterableMappingStrategy()`, the value from the annotation takes precedence. +If a strategy is given for a specific iterable mapping via `@IterableMapping#nullValueMappingStrategy()`, it takes precedence over both `@Mapper#nullValueIterableMappingStrategy()` and the option. +|`RETURN_NULL` + +|`mapstruct.nullValueMapMappingStrategy` +|The strategy to be applied when `null` is passed as a source value to a map mapping. + +Supported values are: + +* `RETURN_NULL`: if `null` is passed as a source value, then `null` will be returned +* `RETURN_DEFAULT`: if `null` is passed then a default value (empty map) will be returned + +If a strategy is given for a specific mapper via `@Mapper#nullValueMapMappingStrategy()`, the value from the annotation takes precedence. +If a strategy is given for a specific map mapping via `@MapMapping#nullValueMappingStrategy()`, it takes precedence over both `@Mapper#nullValueMapMappingStrategy()` and the option. +|`RETURN_NULL` +|=== + +=== Using MapStruct with the Java Module System + +MapStruct can be used with Java 9 and higher versions. + +To allow usage of the `@Generated` annotation `java.annotation.processing.Generated` (part of the `java.compiler` module) can be enabled. + +=== IDE Integration + +There are optional MapStruct plugins for IntelliJ and Eclipse that allow you to have additional completion support (and more) in the annotations. + +==== IntelliJ + +The https://plugins.jetbrains.com/plugin/10036-mapstruct-support[MapStruct IntelliJ] plugin offers assistance in projects that use MapStruct. + +Some features include: + +* Code completion in `target`, `source`, `expression` +* Go To Declaration for properties in `target` and `source` +* Find Usages of properties in `target` and `source` +* Refactoring support +* Errors and Quick Fixes + +==== Eclipse + +The https://marketplace.eclipse.org/content/mapstruct-eclipse-plugin[MapStruct Eclipse] Plugin offers assistance in projects that use MapStruct. + +Some features include: + +* Code completion in `target` and `source` +* Quick Fixes + +[[kotlin-setup]] +=== Kotlin Support + +MapStruct provides support for Kotlin interoperability with Java. + +When using MapStruct with Kotlin, it's recommended to add the `org.jetbrains.kotlin:kotlin-metadata-jvm` library to enable proper introspection of Kotlin metadata: + +.Maven configuration for Kotlin support +==== +[source, xml, linenums] +[subs="verbatim,attributes"] +---- +... + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.14.1 + + + + org.mapstruct + mapstruct-processor + ${org.mapstruct.version} + + + org.jetbrains.kotlin + kotlin-metadata-jvm + ${kotlin.version} + + + + + + +---- +==== + +.Gradle configuration for Kotlin support +==== +[source, groovy, linenums] +[subs="verbatim,attributes"] +---- +dependencies { + implementation "org.mapstruct:mapstruct:${mapstructVersion}" + + annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" + annotationProcessor "org.jetbrains.kotlin:kotlin-metadata-jvm:${kotlinVersion}" +} +---- +==== + +[NOTE] +==== +The `org.jetbrains.kotlin:kotlin-metadata-jvm` dependency is optional but highly recommended when working with Kotlin and Java. +Without it, MapStruct will still work but may not handle complex Kotlin scenarios optimally. +==== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/chapter-3-defining-a-mapper.asciidoc b/documentation/src/main/asciidoc/chapter-3-defining-a-mapper.asciidoc new file mode 100644 index 0000000000..96c76fc20d --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-3-defining-a-mapper.asciidoc @@ -0,0 +1,1281 @@ +[[defining-mapper]] +== Defining a mapper + +In this section you'll learn how to define a bean mapper with MapStruct and which options you have to do so. + +[[basic-mappings]] +=== Basic mappings + +To create a mapper simply define a Java interface with the required mapping method(s) and annotate it with the `org.mapstruct.Mapper` annotation: + +.Java interface to define a mapper +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(target = "manufacturer", source = "make") + @Mapping(target = "seatCount", source = "numberOfSeats") + CarDto carToCarDto(Car car); + + @Mapping(target = "fullName", source = "name") + PersonDto personToPersonDto(Person person); +} +---- +==== + +The `@Mapper` annotation causes the MapStruct code generator to create an implementation of the `CarMapper` interface during build-time. + +In the generated method implementations all readable properties from the source type (e.g. `Car`) will be copied into the corresponding property in the target type (e.g. `CarDto`): + +* When a property has the same name as its target entity counterpart, it will be mapped implicitly. +* When a property has a different name in the target entity, its name can be specified via the `@Mapping` annotation. + +[TIP] +==== +The property name as defined in the http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html[JavaBeans specification] must be specified in the `@Mapping` annotation, e.g. _seatCount_ for a property with the accessor methods `getSeatCount()` and `setSeatCount()`. +==== +[TIP] +==== +By means of the `@BeanMapping(ignoreByDefault = true)` the default behavior will be *explicit mapping*, meaning that all mappings (including nested ones) have to be specified by means of the `@Mapping` and no warnings will be issued on missing target properties. +This allows to ignore all fields, except the ones that are explicitly defined through `@Mapping`. +==== +[TIP] +==== +Fluent setters are also supported. +Fluent setters are setters that return the same type as the type being modified. + +E.g. + +``` +public Builder seatCount(int seatCount) { + this.seatCount = seatCount; + return this; +} +``` +==== + + +To get a better understanding of what MapStruct does have a look at the following implementation of the `carToCarDto()` method as generated by MapStruct: + +.Code generated by MapStruct +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CarMapperImpl implements CarMapper { + + @Override + public CarDto carToCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + + if ( car.getFeatures() != null ) { + carDto.setFeatures( new ArrayList( car.getFeatures() ) ); + } + carDto.setManufacturer( car.getMake() ); + carDto.setSeatCount( car.getNumberOfSeats() ); + carDto.setDriver( personToPersonDto( car.getDriver() ) ); + carDto.setPrice( String.valueOf( car.getPrice() ) ); + if ( car.getCategory() != null ) { + carDto.setCategory( car.getCategory().toString() ); + } + carDto.setEngine( engineToEngineDto( car.getEngine() ) ); + + return carDto; + } + + @Override + public PersonDto personToPersonDto(Person person) { + //... + } + + private EngineDto engineToEngineDto(Engine engine) { + if ( engine == null ) { + return null; + } + + EngineDto engineDto = new EngineDto(); + + engineDto.setHorsePower(engine.getHorsePower()); + engineDto.setFuel(engine.getFuel()); + + return engineDto; + } +} +---- +==== + +The general philosophy of MapStruct is to generate code which looks as much as possible as if you had written it yourself from hand. In particular this means that the values are copied from source to target by plain getter/setter invocations instead of reflection or similar. + +As the example shows the generated code takes into account any name mappings specified via `@Mapping`. +If the type of a mapped attribute is different in source and target entity, +MapStruct will either apply an automatic conversion (as e.g. for the _price_ property, see also <>) +or optionally invoke / create another mapping method (as e.g. for the _driver_ / _engine_ property, see also <>). +MapStruct will only create a new mapping method if and only if the source and target property are properties of a Bean and they themselves are Beans or simple properties. +i.e. they are not `Collection` or `Map` type properties. + +Collection-typed attributes with the same element type will be copied by creating a new instance of the target collection type containing the elements from the source property. For collection-typed attributes with different element types each element will be mapped individually and added to the target collection (see <>). + +MapStruct takes all public properties of the source and target types into account. This includes properties declared on super-types. + +[[mapping-composition]] +=== Mapping Composition +MapStruct supports the use of meta annotations. The `@Mapping` annotation supports now `@Target` with `ElementType#ANNOTATION_TYPE` in addition to `ElementType#METHOD`. This allows `@Mapping` to be used on other (user defined) annotations for re-use purposes. For example: + +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Retention(RetentionPolicy.CLASS) +@Mapping(target = "id", ignore = true) +@Mapping(target = "creationDate", expression = "java(new java.util.Date())") +@Mapping(target = "name", source = "groupName") +public @interface ToEntity { } +---- +==== + +Can be used to characterise an `Entity` without the need to have a common base type. For instance, `ShelveEntity` and `BoxEntity` do not share a common base type in the `StorageMapper` below. +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface StorageMapper { + + StorageMapper INSTANCE = Mappers.getMapper( StorageMapper.class ); + + @ToEntity + @Mapping( target = "weightLimit", source = "maxWeight") + ShelveEntity map(ShelveDto source); + + @ToEntity + @Mapping( target = "label", source = "designation") + BoxEntity map(BoxDto source); +} +---- +==== + +Still, they do have some properties in common. The `@ToEntity` assumes both target beans `ShelveEntity` and `BoxEntity` have properties: `"id"`, `"creationDate"` and `"name"`. It furthermore assumes that the source beans `ShelveDto` and `BoxDto` always have a property `"groupName"`. This concept is also known as "duck-typing". In other words, if it quacks like duck, walks like a duck its probably a duck. + +Error messages are not mature yet: the method on which the problem occurs is displayed, as well as the concerned values in the `@Mapping` annotation. However, the composition aspect is not visible. The messages are "as if" the `@Mapping` would be present on the concerned method directly. +Therefore, the user should use this feature with care, especially when uncertain when a property is always present. + +A more typesafe (but also more verbose) way would be to define base classes / interfaces on the target bean and the source bean and use `@InheritConfiguration` to achieve the same result (see <>). + +[[adding-custom-methods]] +=== Adding custom methods to mappers + +In some cases it can be required to manually implement a specific mapping from one type to another which can't be generated by MapStruct. One way to handle this is to implement the custom method on another class which then is used by mappers generated by MapStruct (see <>). + +Alternatively, when using Java 8 or later, you can implement custom methods directly in a mapper interface as default methods. The generated code will invoke the default methods if the argument and return types match. + +As an example let's assume the mapping from `Person` to `PersonDto` requires some special logic which can't be generated by MapStruct. You could then define the mapper from the previous example like this: + +.Mapper which defines a custom mapping with a default method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(...) + ... + CarDto carToCarDto(Car car); + + default PersonDto personToPersonDto(Person person) { + //hand-written mapping logic + } +} +---- +==== + +The class generated by MapStruct implements the method `carToCarDto()`. The generated code in `carToCarDto()` will invoke the manually implemented `personToPersonDto()` method when mapping the `driver` attribute. + +A mapper could also be defined in the form of an abstract class instead of an interface and implement the custom methods directly in the mapper class. In this case MapStruct will generate an extension of the abstract class with implementations of all abstract methods. An advantage of this approach over declaring default methods is that additional fields could be declared in the mapper class. + +The previous example where the mapping from `Person` to `PersonDto` requires some special logic could then be defined like this: + +.Mapper defined by an abstract class +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public abstract class CarMapper { + + @Mapping(...) + ... + public abstract CarDto carToCarDto(Car car); + + public PersonDto personToPersonDto(Person person) { + //hand-written mapping logic + } +} +---- +==== + +MapStruct will generate a sub-class of `CarMapper` with an implementation of the `carToCarDto()` method as it is declared abstract. The generated code in `carToCarDto()` will invoke the manually implemented `personToPersonDto()` method when mapping the `driver` attribute. + +[[mappings-with-several-source-parameters]] +=== Mapping methods with several source parameters + +MapStruct also supports mapping methods with several source parameters. This is useful e.g. in order to combine several entities into one data transfer object. The following shows an example: + +.Mapping method with several source parameters +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface AddressMapper { + + @Mapping(target = "description", source = "person.description") + @Mapping(target = "houseNumber", source = "address.houseNo") + DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address); +} +---- +==== + +The shown mapping method takes two source parameters and returns a combined target object. As with single-parameter mapping methods properties are mapped by name. + +In case several source objects define a property with the same name, the source parameter from which to retrieve the property must be specified using the `@Mapping` annotation as shown for the `description` property in the example. An error will be raised when such an ambiguity is not resolved. For properties which only exist once in the given source objects it is optional to specify the source parameter's name as it can be determined automatically. + +[WARNING] +==== +Specifying the parameter in which the property resides is mandatory when using the `@Mapping` annotation. +==== + +[TIP] +==== +Mapping methods with several source parameters will return `null` in case all the source parameters are `null`. Otherwise the target object will be instantiated and all properties from the provided parameters will be propagated. +==== + +MapStruct also offers the possibility to directly refer to a source parameter. + +.Mapping method directly referring to a source parameter +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface AddressMapper { + + @Mapping(target = "description", source = "person.description") + @Mapping(target = "houseNumber", source = "hn") + DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Integer hn); +} +---- +==== + +In this case the source parameter is directly mapped into the target as the example above demonstrates. The parameter `hn`, a non bean type (in this case `java.lang.Integer`) is mapped to `houseNumber`. + +[[mapping-nested-bean-properties-to-current-target]] +=== Mapping nested bean properties to current target + +If you don't want explicitly name all properties from nested source bean, you can use `.` as target. + This will tell MapStruct to map every property from source bean to target object. The following shows an example: + +.use of "target this" annotation "." +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- + @Mapper + public interface CustomerMapper { + + @Mapping( target = "name", source = "record.name" ) + @Mapping( target = ".", source = "record" ) + @Mapping( target = ".", source = "account" ) + Customer customerDtoToCustomer(CustomerDto customerDto); + } +---- +==== + +The generated code will map every property from `CustomerDto.record` to `Customer` directly, without need to manually name any of them. +The same goes for `Customer.account`. + +When there are conflicts, these can be resolved by explicitly defining the mapping. For instance in the example above. `name` occurs in `CustomerDto.record` and in `CustomerDto.account`. The mapping `@Mapping( target = "name", source = "record.name" )` resolves this conflict. + + +This "target this" notation can be very useful when mapping hierarchical objects to flat objects and vice versa (`@InheritInverseConfiguration`). + + + +[[updating-bean-instances]] +=== Updating existing bean instances + +In some cases you need mappings which don't create a new instance of the target type but instead update an existing instance of that type. This sort of mapping can be realized by adding a parameter for the target object and marking this parameter with `@MappingTarget`. The following shows an example: + +.Update method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + void updateCarFromDto(CarDto carDto, @MappingTarget Car car); +} +---- +==== + +The generated code of the `updateCarFromDto()` method will update the passed `Car` instance with the properties from the given `CarDto` object. There may be only one parameter marked as mapping target. Instead of `void` you may also set the method's return type to the type of the target parameter, which will cause the generated implementation to update the passed mapping target and return it as well. This allows for fluent invocations of mapping methods. + +For `CollectionMappingStrategy.ACCESSOR_ONLY` Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map. Otherwise, For `CollectionMappingStrategy.ADDER_PREFERRED` or `CollectionMappingStrategy.TARGET_IMMUTABLE` the target will not be cleared and the values will be populated immediately. + +[[direct-field-mappings]] +=== Mappings with direct field access + +MapStruct also supports mappings of `public` fields that have no getters/setters. MapStruct will +use the fields as read/write accessor if it cannot find suitable getter/setter methods for the property. + +A field is considered as a read accessor if it is `public` or `public final`. If a field is `static` it is not +considered as a read accessor. + +A field is considered as a write accessor only if it is `public`. If a field is `final` and/or `static` it is not +considered as a write accessor. + +Small example: + +.Example classes for mapping +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Customer { + + private Long id; + private String name; + + //getters and setter omitted for brevity +} + +public class CustomerDto { + + public Long id; + public String customerName; +} + +@Mapper +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "name", source = "customerName") + Customer toCustomer(CustomerDto customerDto); + + @InheritInverseConfiguration + CustomerDto fromCustomer(Customer customer); +} +---- +==== + +For the configuration from above, the generated mapper looks like: + +.Generated mapper for example classes +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CustomerMapperImpl implements CustomerMapper { + + @Override + public Customer toCustomer(CustomerDto customerDto) { + // ... + customer.setId( customerDto.id ); + customer.setName( customerDto.customerName ); + // ... + } + + @Override + public CustomerDto fromCustomer(Customer customer) { + // ... + customerDto.id = customer.getId(); + customerDto.customerName = customer.getName(); + // ... + } +} +---- +==== + +You can find the complete example in the +https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-field-mapping[mapstruct-examples-field-mapping] +project on GitHub. + +[[mapping-with-builders]] +=== Using builders + +MapStruct also supports mapping of immutable types via builders. +When performing a mapping MapStruct checks if there is a builder for the type being mapped. +This is done via the `BuilderProvider` SPI. +If a Builder exists for a certain type, then that builder will be used for the mappings. + +The default implementation of the `BuilderProvider` assumes the following: + +* The type has either +** A parameterless public static builder creation method that returns a builder. +e.g. `Person` has a public static method that returns `PersonBuilder`. +** A public static inner class with the name having the suffix "Builder", and a public no-args constructor +e.g. `Person` has an inner class `PersonBuilder` with a public no-args constructor. +* The builder type has a parameterless public method (build method) that returns the type being built. +In our example `PersonBuilder` has a method returning `Person`. +* In case there are multiple build methods, MapStruct will look for a method called `build`, if such method exists +then this would be used, otherwise a compilation error would be created. +* A specific build method can be defined by using `@Builder` within: `@BeanMapping`, `@Mapper` or `@MapperConfig` +* In case there are multiple builder creation methods that satisfy the above conditions then a `MoreThanOneBuilderCreationMethodException` +will be thrown from the `DefaultBuilderProvider` SPI. +In case of a `MoreThanOneBuilderCreationMethodException` MapStruct will write a warning in the compilation and not use any builder. + +If such type is found then MapStruct will use that type to perform the mapping to (i.e. it will look for setters into that type). +To finish the mapping MapStruct generates code that will invoke the build method of the builder. + +[NOTE] +====== +Builder detection can be switched off by means of `@Builder#disableBuilder`. MapStruct will fall back on regular getters / setters in case builders are disabled. +====== + +[NOTE] +====== +The <> are also considered for the builder type. +E.g. If an object factory exists for our `PersonBuilder` then this factory would be used instead of the builder creation method. +====== + +[NOTE] +====== +Detected builders influence `@BeforeMapping` and `@AfterMapping` behavior. See <> for more information. +====== + +.Person with Builder example +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Person { + + private final String name; + + protected Person(Person.Builder builder) { + this.name = builder.name; + } + + public static Person.Builder builder() { + return new Person.Builder(); + } + + public static class Builder { + + private String name; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Person create() { + return new Person( this ); + } + } +} +---- +==== + +.Person Mapper definition +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public interface PersonMapper { + + Person map(PersonDto dto); +} +---- +==== + +.Generated mapper with builder +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class PersonMapperImpl implements PersonMapper { + + public Person map(PersonDto dto) { + if (dto == null) { + return null; + } + + Person.Builder builder = Person.builder(); + + builder.name( dto.getName() ); + + return builder.create(); + } +} +---- +==== + +Supported builder frameworks: + +* https://projectlombok.org/[Lombok] - It is required to have the Lombok classes in a separate module. +See for more information at https://github.com/rzwitserloot/lombok/issues/1538[rzwitserloot/lombok#1538] and to set up Lombok with MapStruct, refer to <>. +* https://github.com/google/auto/blob/master/value/userguide/index.md[AutoValue] +* https://immutables.github.io/[Immutables] - When Immutables are present on the annotation processor path then the `ImmutablesAccessorNamingStrategy` and `ImmutablesBuilderProvider` would be used by default +* https://github.com/google/FreeBuilder[FreeBuilder] - When FreeBuilder is present on the annotation processor path then the `FreeBuilderAccessorNamingStrategy` would be used by default. +When using FreeBuilder then the JavaBean convention should be followed, otherwise MapStruct won't recognize the fluent getters. +* It also works for custom builders (handwritten ones) if the implementation supports the defined rules for the default `BuilderProvider`. +Otherwise, you would need to write a custom `BuilderProvider` + +[TIP] +==== +In case you want to disable using builders then you can pass the MapStruct processor option `mapstruct.disableBuilders` to the compiler. e.g. `-Amapstruct.disableBuilders=true`. +==== + +[[mapping-with-constructors]] +=== Using Constructors + +MapStruct supports using constructors for mapping target types. +When doing a mapping MapStruct checks if there is a builder for the type being mapped. +If there is no builder, then MapStruct looks for a single accessible constructor. +When there are multiple constructors then the following is done to pick the one which should be used: + +* If a constructor is annotated with an annotation _named_ `@Default` (from any package, see <>) it will be used. +* If a single public constructor exists then it will be used to construct the object, and the other non public constructors will be ignored. +* If a parameterless constructor exists then it will be used to construct the object, and the other constructors will be ignored. +* If there are multiple eligible constructors then there will be a compilation error due to ambiguous constructors. In order to break the ambiguity an annotation _named_ `@Default` (from any package, see <>) can used. + +.Deciding which constructor to use +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Vehicle { + + protected Vehicle() { } + + // MapStruct will use this constructor, because it is a single public constructor + public Vehicle(String color) { } +} + +public class Car { + + // MapStruct will use this constructor, because it is a parameterless empty constructor + public Car() { } + + public Car(String make, String color) { } +} + +public class Truck { + + public Truck() { } + + // MapStruct will use this constructor, because it is annotated with @Default + @Default + public Truck(String make, String color) { } +} + +public class Van { + + // There will be a compilation error when using this class because MapStruct cannot pick a constructor + + public Van(String make) { } + + public Van(String make, String color) { } + +} +---- +==== + +When using a constructor then the names of the parameters of the constructor will be used and matched to the target properties. +When the constructor has an annotation _named_ `@ConstructorProperties` (from any package, see <>) then this annotation will be used to get the names of the parameters. + +[NOTE] +==== +When an object factory method or a method annotated with `@ObjectFactory` exists, it will take precedence over any constructor defined in the target. +The target object constructor will not be used in that case. +==== + + +.Person with constructor parameters +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Person { + + private final String name; + private final String surname; + + public Person(String name, String surname) { + this.name = name; + this.surname = surname; + } +} +---- +==== + +.Person With Constructor Mapper definition +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public interface PersonMapper { + + Person map(PersonDto dto); +} +---- +==== + +.Generated mapper with constructor +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class PersonMapperImpl implements PersonMapper { + + public Person map(PersonDto dto) { + if (dto == null) { + return null; + } + + String name; + String surname; + name = dto.getName(); + surname = dto.getSurname(); + + Person person = new Person( name, surname ); + + return person; + } +} +---- +==== + +[[mapping-with-optional]] +=== Using Optional + +MapStruct provides comprehensive support for Java's `Optional` type, allowing you to use `Optional` as both source and target types in your mappings. +MapStruct handles all common `Optional` mapping scenarios, including conversions, nested properties, update mappings, and integration with builders and constructors. + +[[optional-basic-behavior]] +==== Basic Optional Behavior + +When using `Optional` as a source type, MapStruct performs presence checks using `Optional.isEmpty()` / `!Optional.isPresent()` instead of `null` checks. +When using `Optional` as a target type, MapStruct returns `Optional.empty()` instead of `null` when the source is absent. + +[[optional-mapping-scenarios]] +==== Optional Mapping Scenarios + +MapStruct supports three primary mapping scenarios with `Optional`: + +1. `Optional` to `Optional` - Both source and target are wrapped in `Optional` +2. `Optional` to Non-`Optional` - Source is `Optional`, target is a regular type +3. Non-`Optional` to `Optional` - Source is a regular type, target is `Optional` + +.Example mapper showing all Optional scenarios +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface ProductMapper { + + Optional map(Optional product); + + ProductDto unwrap(Optional product); + + Optional wrap(Product product); +} +---- +==== + +.Generated code for `Optional` to `Optional` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +@Override +public Optional map(Optional product) { + if ( product.isEmpty() ) { + return Optional.empty(); + } + + Product productValue = product.get(); + + ProductDto productDto = new ProductDto(); + + productDto.setName( productValue.getName() ); + productDto.setPrice( productValue.getPrice() ); + + return Optional.of( productDto ); +} +---- +==== + +.Generated code for `Optional` to Non-`Optional` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +@Override +public ProductDto unwrap(Optional product) { + if ( product.isEmpty() ) { + return null; + } + + Product productValue = product.get(); + + ProductDto productDto = new ProductDto(); + + productDto.setName( productValue.getName() ); + productDto.setPrice( productValue.getPrice() ); + + return productDto; +} +---- +==== + +.Generated code for Non-`Optional` to `Optional` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +@Override +public Optional wrap(Product product) { + if ( product == null ) { + return Optional.empty(); + } + + ProductDto productDto = new ProductDto(); + + productDto.setName( product.getName() ); + productDto.setPrice( product.getPrice() ); + + return Optional.of( productDto ); +} +---- +==== + +[[optional-properties]] +==== Mapping Optional Properties + +MapStruct handles `Optional` properties within your beans seamlessly. +When mapping `Optional` properties, MapStruct generates appropriate presence checks before accessing the values. + +.Example with `Optional` properties +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Car { + private Optional make; + private Optional numberOfSeats; + private Person driver; + + // getters omitted for brevity +} + +public class CarDto { + private String manufacturer; + private int seatCount; + private PersonDto driver; + + // getters and setters omitted for brevity +} + +@Mapper +public interface CarMapper { + + @Mapping(target = "manufacturer", source = "make") + @Mapping(target = "seatCount", source = "numberOfSeats") + CarDto carToCarDto(Car car); +} +---- +==== + +.Code generated by MapStruct for `Optional` properties +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CarMapperImpl implements CarMapper { + + @Override + public CarDto carToCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + + if ( car.getMake().isPresent() ) { + carDto.setManufacturer( car.getMake().get() ); + } + if ( car.getNumberOfSeats().isPresent() ) { + carDto.setSeatCount( car.getNumberOfSeats().get() ); + } + carDto.setDriver( personToPersonDto( car.getDriver() ) ); + + return carDto; + } + + protected PersonDto personToPersonDto(Person person) { + //... + } +} +---- +==== + +[[optional-update-mappings]] +==== Update Mappings with Optional + +`Optional` works seamlessly with update mappings using `@MappingTarget`. +When the source `Optional` is present, the target object is updated with the unwrapped value. +When the source `Optional` is empty, the behavior depends on the null value property mapping strategy. + +.Update mapping with an `Optional` source +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface ProductUpdateMapper { + + void updateProduct(ProductUpdateDto dto, @MappingTarget Product product); +} + +public class ProductUpdateDto { + private Optional name; + private Optional price; + + // getters omitted +} + +public class Product { + private String name; + private BigDecimal price; + + // getters and setters omitted +} +---- +==== + +.Generated update method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +@Override +public void updateProduct(ProductUpdateDto dto, Product product) { + if ( dto == null ) { + return; + } + + if ( dto.getName().isPresent() ) { + product.setName( dto.getName().get() ); + } + if ( dto.getPrice().isPresent() ) { + product.setPrice( dto.getPrice().get() ); + } +} +---- +==== + +[[optional-null-value-strategies]] +==== Null Value Mapping Strategies + +When working with `Optional` types, MapStruct's null value mapping strategies behave as follows: + +* For `Optional` return types: `NullValueMappingStrategy.RETURN_DEFAULT` will return `Optional.empty()` instead of `null` +* For `Optional` properties: When a source property `Optional` is empty, `NullValuePropertyMappingStrategy` determines whether to skip the property, set it to null/empty, or use a default value +* `IGNORE` strategy: When a source `Optional` is empty, the target property is not updated +* `SET_TO_NULL` strategy: When a source `Optional` is empty, the target property is set to `null` (for non-`Optional` targets) or `Optional.empty()` (for `Optional` targets) +* `SET_TO_DEFAULT` strategy: When a source `Optional` is empty, the target property is set to its default value + +.Using null value strategies with `Optional` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface ProductMapper { + + void updateProduct(ProductUpdateDto dto, @MappingTarget Product product); +} +---- +==== + +With the `IGNORE` strategy, when Optional properties are empty, they won't overwrite existing target values. + +[[optional-builders-constructors]] +==== Optional with Builders and Constructors + +MapStruct's Optional support works seamlessly with both builder patterns and constructor-based mappings. + +.Optional with builders +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface PersonMapper { + Optional map(Optional person); +} + +public class PersonDto { + private final String name; + private final Integer age; + + private PersonDto(Builder builder) { + this.name = builder.name; + this.age = builder.age; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String name; + private Integer age; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder age(Integer age) { + this.age = age; + return this; + } + + public PersonDto build() { + return new PersonDto(this); + } + } + + // getters omitted +} +---- +==== + +.Generated code using builder +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +@Override +public Optional map(Optional person) { + if ( person.isEmpty() ) { + return Optional.empty(); + } + + Person personValue = person.get(); + + PersonDto.Builder builder = PersonDto.builder(); + + builder.name( personValue.getName() ); + builder.age( personValue.getAge() ); + + return Optional.of( builder.build() ); +} +---- +==== + +.Optional with constructors +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class PersonDto { + private final String name; + private final Integer age; + + public PersonDto(String name, Integer age) { + this.name = name; + this.age = age; + } + + // getters omitted +} +---- +==== + +When the target type uses constructors and has `Optional` properties, MapStruct will properly handle the `Optional` parameters. + +[[optional-complex-mappings]] +==== Complex Optional Mappings + +MapStruct can handle complex scenarios where `Optional` is combined with nested object mappings, collections, and custom mapping methods. + +.Complex nested Optional mappings +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface OrderMapper { + + OrderDto map(Order order); + + // MapStruct will automatically use this for nested mappings + CustomerDto map(Customer customer); +} + +public class Order { + private Optional customer; + private Optional
    shippingAddress; + + // getters omitted +} + +public class OrderDto { + private Optional customer; + private AddressDto shippingAddress; + + // getters and setters omitted +} +---- +==== + +When mapping nested objects that are wrapped in Optional, MapStruct will: + +1. Check if the source `Optional` is present +2. Extract the value from the `Optional` +3. Map the extracted value to the target type +4. Wrap the result in an `Optional` if the target is also Optional + +[[optional-best-practices]] +==== Best Practices and Limitations + +[NOTE] +==== +While MapStruct fully supports `Optional` for target properties (public fields or setter parameters), the Java community generally recommends using `Optional` only for return types (source properties / getters). +Consider your team's coding standards when deciding whether to use `Optional` for target properties. +==== + +[WARNING] +==== +Avoid using `null` when returning `Optional` values to prevent `NullPointerException`. +MapStruct assumes that if you're using `Optional`, the `Optional` itself is not null. +==== + +[[mapping-map-to-bean]] +=== Mapping Map to Bean + +There are situations when a mapping from a `Map` into a specific bean is needed. +MapStruct offers a transparent way of doing such a mapping by using the target bean properties (or defined through `Mapping#source`) to extract the values from the map. +Such a mapping looks like: + +.Example classes for mapping map to bean +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Customer { + + private Long id; + private String name; + + //getters and setter omitted for brevity +} + +@Mapper +public interface CustomerMapper { + + @Mapping(target = "name", source = "customerName") + Customer toCustomer(Map map); + +} +---- +==== + +.Generated mapper for mapping map to bean +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CustomerMapperImpl implements CustomerMapper { + + @Override + public Customer toCustomer(Map map) { + // ... + if ( map.containsKey( "id" ) ) { + customer.setId( Integer.parseInt( map.get( "id" ) ) ); + } + if ( map.containsKey( "customerName" ) ) { + customer.setName( map.get( "customerName" ) ); + } + // ... + } +} +---- +==== + +[NOTE] +==== +All existing rules about mapping between different types and using other mappers defined with `Mapper#uses` or custom methods in the mappers are applied. +i.e. You can map from `Map` where for each property a conversion from `Integer` into the respective property will be needed. +==== + +[WARNING] +==== +When a raw map or a map that does not have a String as a key is used, then a warning will be generated. +The warning is not generated if the map itself is mapped into some other target property directly as is. +==== + +[[adding-annotations]] +=== Adding annotations + +Other frameworks sometimes requires you to add annotations to certain classes so that they can easily detect the mappers. +Using the `@AnnotateWith` annotation you can generate an annotation at the specified location. + +For example Apache Camel has a `@Converter` annotation which you can apply to generated mappers using the `@AnnotateWith` annotation. + +.AnnotateWith source example +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +@AnnotateWith( + value = Converter.class, + elements = @AnnotateWith.Element( name = "generateBulkLoader", booleans = true ) +) +public interface MyConverter { + @AnnotateWith( Converter.class ) + DomainObject map( DtoObject dto ); +} +---- +==== + +.AnnotateWith generated mapper +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Converter( generateBulkLoader = true ) +public class MyConverterImpl implements MyConverter { + @Converter + public DomainObject map( DtoObject dto ) { + // default mapping behaviour + } +} +---- +==== + + +[[javadoc]] +=== Adding Javadoc comments + +MapStruct provides support for defining Javadoc comments in the generated mapper implementation using the +`org.mapstruct.Javadoc` annotation. + +This functionality could be relevant especially in situations where certain Javadoc standards need to be met or +to deal with Javadoc validation constraints. + +The `@Javadoc` annotation defines attributes for the different Javadoc elements. + +Consider the following example: + +.Javadoc annotation example +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +@Javadoc( + value = "This is the description", + authors = { "author1", "author2" }, + deprecated = "Use {@link OtherMapper} instead", + since = "0.1" +) +public interface MyAnnotatedWithJavadocMapper { + //... +} +---- +==== + +.Javadoc annotated generated mapper +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +/** +* This is the description +* +* @author author1 +* @author author2 +* +* @deprecated Use {@link OtherMapper} instead +* @since 0.1 +*/ +public class MyAnnotatedWithJavadocMapperImpl implements MyAnnotatedWithJavadocMapper { + //... +} +---- +==== + +The entire Javadoc comment block can be provided directly as well. + +.Javadoc annotation example with the entire Javadoc comment block provided directly +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +@Javadoc( + "This is the description\n" + + "\n" + + "@author author1\n" + + "@author author2\n" + + "\n" + + "@deprecated Use {@link OtherMapper} instead\n" + + "@since 0.1\n" +) +public interface MyAnnotatedWithJavadocMapper { + //... +} +---- +==== + +Or using Text blocks: + +.Javadoc annotation example with the entire Javadoc comment block provided directly using Text blocks +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +@Javadoc( + """ + This is the description + + @author author1 + @author author2 + + @deprecated Use {@link OtherMapper} instead + @since 0.1 + """ +) +public interface MyAnnotatedWithJavadocMapper { + //... +} +---- +==== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc b/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc new file mode 100644 index 0000000000..ec817e0cdf --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-4-retrieving-a-mapper.asciidoc @@ -0,0 +1,153 @@ +[[retrieving-mapper]] +== Retrieving a mapper + +[[mappers-factory]] +=== The Mappers factory (no dependency injection) + +When not using a DI framework, Mapper instances can be retrieved via the `org.mapstruct.factory.Mappers` class. Just invoke the `getMapper()` method, passing the interface type of the mapper to return: + +.Using the Mappers factory +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +CarMapper mapper = Mappers.getMapper( CarMapper.class ); +---- +==== + +By convention, a mapper interface should define a member called `INSTANCE` which holds a single instance of the mapper type: + +.Declaring an instance of a mapper (interface) +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + CarDto carToCarDto(Car car); +} + +---- +==== + +.Declaring an instance of a mapper (abstract class) +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public abstract class CarMapper { + + public static final CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + CarDto carToCarDto(Car car); +} + +---- +==== + +This pattern makes it very easy for clients to use mapper objects without repeatedly instantiating new instances: + +.Accessing a mapper +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +Car car = ...; +CarDto dto = CarMapper.INSTANCE.carToCarDto( car ); +---- +==== + + +Note that mappers generated by MapStruct are stateless and thread-safe and thus can safely be accessed from several threads at the same time. + +[[using-dependency-injection]] +=== Using dependency injection + +If you're working with a dependency injection framework such as http://jcp.org/en/jsr/detail?id=346[CDI] (Contexts and Dependency Injection for Java^TM^ EE) or the http://www.springsource.org/spring-framework[Spring Framework], it is recommended to obtain mapper objects via dependency injection and *not* via the `Mappers` class as described above. For that purpose you can specify the component model which generated mapper classes should be based on either via `@Mapper#componentModel` or using a processor option as described in <>. + +Currently there is support for CDI and Spring (the latter either via its custom annotations or using the JSR 330 annotations). See <> for the allowed values of the `componentModel` attribute which are the same as for the `mapstruct.defaultComponentModel` processor option and constants are defined in a class `MappingConstants.ComponentModel`. In both cases the required annotations will be added to the generated mapper implementations classes in order to make the same subject to dependency injection. The following shows an example using CDI: + +.A mapper using the CDI component model +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(componentModel = MappingConstants.ComponentModel.CDI) +public interface CarMapper { + + CarDto carToCarDto(Car car); +} + +---- +==== + +The generated mapper implementation will be marked with the `@ApplicationScoped` annotation and thus can be injected into fields, constructor arguments etc. using the `@Inject` annotation: + +.Obtaining a mapper via dependency injection +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Inject +private CarMapper mapper; +---- +==== + +A mapper which uses other mapper classes (see <>) will obtain these mappers using the configured component model. So if `CarMapper` from the previous example was using another mapper, this other mapper would have to be an injectable CDI bean as well. + +[[injection-strategy]] +=== Injection strategy + +When using <>, you can choose between constructor, field, or setter injection. +This can be done by either providing the injection strategy via `@Mapper` or `@MapperConfig` annotation. + +.Using constructor injection +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = EngineMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR) +public interface CarMapper { + CarDto carToCarDto(Car car); +} +---- +==== + +The generated mapper will inject classes defined in the **uses** attribute if MapStruct has detected that it needs to use an instance of it for a mapping. +When `InjectionStrategy#CONSTRUCTOR` is used, the constructor will have the appropriate annotation and the fields won't. +When `InjectionStrategy#FIELD` is used, the annotation is on the field itself. +When `InjectionStrategy#SETTER` is used the annotation is on a generated setter method. +For now, the default injection strategy is field injection, but it can be configured with <>. +It is recommended to use constructor injection to simplify testing. + +When you define mappers in Spring with circular dependencies compilation may fail. +In that case utilize the `InjectionStrategy#SETTER` strategy. + +[TIP] +==== +For abstract classes or decorators setter injection should be used. +==== + +[[class-accessibility]] +=== Class accessibility + +By default, the generated Mapper implementation will have the same accessibility (`public` or none) as the interface or abstract class carrying the `@Mapper` annotation. Especially in conjunction with a DI framework, this might not be desired. If you wish to reduce the visibility of the generated class, you can make use of the `accessibility` attribute like this: + +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, accessibility = ClassAccessibility.PACKAGE_PRIVATE) +public interface CarMapper { + + CarDto carToCarDto(Car car); +} + +---- +==== + +In this case, the generated Mapper will have no modifier. Possible values are `ClassAccessibility.DEFAULT` (the behavior described above), `ClassAccessibility.PUBLIC`, and `ClassAccessibility.PACKAGE_PRIVATE` (no modifier). diff --git a/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc b/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc new file mode 100644 index 0000000000..10c41506de --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-5-data-type-conversions.asciidoc @@ -0,0 +1,842 @@ +[[datatype-conversions]] +== Data type conversions + +Not always a mapped attribute has the same type in the source and target objects. For instance an attribute may be of type `int` in the source bean but of type `Long` in the target bean. + +Another example are references to other objects which should be mapped to the corresponding types in the target model. E.g. the class `Car` might have a property `driver` of the type `Person` which needs to be converted into a `PersonDto` object when mapping a `Car` object. + +In this section you'll learn how MapStruct deals with such data type conversions. + +[[implicit-type-conversions]] +=== Implicit type conversions + +MapStruct takes care of type conversions automatically in many cases. If for instance an attribute is of type `int` in the source bean but of type `String` in the target bean, the generated code will transparently perform a conversion by calling `String#valueOf(int)` and `Integer#parseInt(String)`, respectively. + +Currently the following conversions are applied automatically: + +* Between all Java primitive data types and their corresponding wrapper types, e.g. between `int` and `Integer`, `boolean` and `Boolean` etc. The generated code is `null` aware, i.e. when converting a wrapper type into the corresponding primitive type a `null` check will be performed. + +* Between all Java primitive number types and the wrapper types, e.g. between `int` and `long` or `byte` and `Integer`. + +[WARNING] +==== +Converting from larger data types to smaller ones (e.g. from `long` to `int`) can cause a value or precision loss. The `Mapper` and `MapperConfig` annotations have a method `typeConversionPolicy` to control warnings / errors. Due to backward compatibility reasons the default value is `ReportingPolicy.IGNORE`. +==== + +* Between all Java primitive types (including their wrappers) and `String`, e.g. between `int` and `String` or `Boolean` and `String`. A format string as understood by `java.text.DecimalFormat` can be specified. + +.Conversion from int to String +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(source = "price", numberFormat = "$#.00") + CarDto carToCarDto(Car car); + + @IterableMapping(numberFormat = "$#.00") + List prices(List prices); +} +---- +==== +* Between `enum` types and `String`. + +* Between `enum` types and `Integer`, according to `enum.ordinal()`. +** When converting from an `Integer`, the value needs to be less than the number of values of the enum, otherwise an `ArrayOutOfBoundsException` is thrown. + +* Between big number types (`java.math.BigInteger`, `java.math.BigDecimal`) and Java primitive types (including their wrappers) as well as String. A format string as understood by `java.text.DecimalFormat` can be specified. + +.Conversion from BigDecimal to String +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(source = "power", numberFormat = "#.##E0") + CarDto carToCarDto(Car car); + +} +---- +==== + + +* Between `JAXBElement` and `T`, `List>` and `List` + +* Between `java.util.Calendar`/`java.util.Date` and JAXB's `XMLGregorianCalendar` + +* Between `java.util.Date`/`XMLGregorianCalendar` and `String`. A format string as understood by `java.text.SimpleDateFormat` can be specified via the `dateFormat` option as this: + +.Conversion from Date to String +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + @Mapping(source = "manufacturingDate", dateFormat = "dd.MM.yyyy") + CarDto carToCarDto(Car car); + + @IterableMapping(dateFormat = "dd.MM.yyyy") + List stringListToDateList(List dates); +} +---- +==== + +* Between Jodas `org.joda.time.DateTime`, `org.joda.time.LocalDateTime`, `org.joda.time.LocalDate`, `org.joda.time.LocalTime` and `String`. A format string as understood by `java.text.SimpleDateFormat` can be specified via the `dateFormat` option (see above). + +* Between Jodas `org.joda.time.DateTime` and `javax.xml.datatype.XMLGregorianCalendar`, `java.util.Calendar`. + +* Between Jodas `org.joda.time.LocalDateTime`, `org.joda.time.LocalDate` and `javax.xml.datatype.XMLGregorianCalendar`, `java.util.Date`. + +* Between `java.time.LocalDate`, `java.time.LocalDateTime` and `javax.xml.datatype.XMLGregorianCalendar`. + +* Between `java.time.ZonedDateTime`, `java.time.LocalDateTime`, `java.time.LocalDate`, `java.time.LocalTime` from Java 8 Date-Time package and `String`. A format string as understood by `java.text.SimpleDateFormat` can be specified via the `dateFormat` option (see above). + +* Between `java.time.Instant`, `java.time.Duration`, `java.time.Period` from Java 8 Date-Time package and `String` using the `parse` method in each class to map from `String` and using `toString` to map into `String`. + +* Between `java.time.ZonedDateTime` from Java 8 Date-Time package and `java.util.Date` where, when mapping a `ZonedDateTime` from a given `Date`, the system default timezone is used. + +* Between `java.time.LocalDateTime` from Java 8 Date-Time package and `java.util.Date` where timezone UTC is used as the timezone. + +* Between `java.time.LocalDate` from Java 8 Date-Time package and `java.util.Date` / `java.sql.Date` where timezone UTC is used as the timezone. + +* Between `java.time.Instant` from Java 8 Date-Time package and `java.util.Date`. + +* Between `java.time.LocalDateTime` from Java 8 Date-Time package and `java.time.LocalDate` from the same package. + +* Between `java.time.ZonedDateTime` from Java 8 Date-Time package and `java.time.LocalDateTime` from the same package. + +* Between `java.time.OffsetDateTime` from Java 8 Date-Time package and `java.time.LocalDateTime` from the same package. + +* Between `java.time.ZonedDateTime` from Java 8 Date-Time package and `java.time.Instant` from the same package. + +* Between `java.time.OffsetDateTime` from Java 8 Date-Time package and `java.time.Instant` from the same package. + +* Between `java.time.ZonedDateTime` from Java 8 Date-Time package and `java.util.Calendar`. + +* Between `java.sql.Date` and `java.util.Date` + +* Between `java.sql.Time` and `java.util.Date` + +* Between `java.sql.Timestamp` and `java.util.Date` + +* When converting from a `String`, omitting `Mapping#dateFormat`, it leads to usage of the default pattern and date format symbols for the default locale. An exception to this rule is `XmlGregorianCalendar` which results in parsing the `String` according to http://www.w3.org/TR/xmlschema-2/#dateTime[XML Schema 1.0 Part 2, Section 3.2.7-14.1, Lexical Representation]. + +* Between `java.util.Currency` and `String`. +** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/ISO_4217[ISO-4217] alphabetic code otherwise an `IllegalArgumentException` is thrown. + +* Between `java.util.UUID` and `String`. +** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/Universally_unique_identifier[UUID] otherwise an `IllegalArgumentException` is thrown. + +* Between `String` and `StringBuilder` + +* Between `java.net.URI` and `String`. +** When converting from a `String`, the value needs to be a valid https://datatracker.ietf.org/doc/html/rfc2396[RFC 2396 URI] otherwise an `IllegalArgumentException` is thrown. + +* Between `java.net.URL` and `String`. +** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/URL[URL] otherwise a `MalformedURLException` is thrown. + +* Between `java.util.Locale` and `String`. +** When converting from a `Locale`, the resulting `String` will be a well-formed IETF BCP 47 language tag representing the locale. When converting from a `String`, the locale that best represents the language tag will be returned. See https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#forLanguageTag-java.lang.String-[Locale.forLanguageTag()] and https://docs.oracle.com/javase/8/docs/api/java/util/Locale.html#toLanguageTag--[Locale.toLanguageTag()] for more information. + +[NOTE] +==== +All the above conversions also work when the source or target type is wrapped in `java.util.Optional`, `java.util.OptionalDouble`, `java.util.OptionalLong` or `java.util.OptionalInt`. +For example, `Optional` can be converted to `String`, `int` can be converted to `Optional`, +or `Optional` can be converted to `Integer`. +The same conversion rules apply, with MapStruct automatically handling the wrapping and unwrapping of `Optional` values. +==== + +[[mapping-object-references]] +=== Mapping object references + +Typically an object has not only primitive attributes but also references other objects. E.g. the `Car` class could contain a reference to a `Person` object (representing the car's driver) which should be mapped to a `PersonDto` object referenced by the `CarDto` class. + +In this case just define a mapping method for the referenced object type as well: + +.Mapper with one mapping method using another +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + CarDto carToCarDto(Car car); + + PersonDto personToPersonDto(Person person); +} +---- +==== + +The generated code for the `carToCarDto()` method will invoke the `personToPersonDto()` method for mapping the `driver` attribute, while the generated implementation for `personToPersonDto()` performs the mapping of person objects. + +That way it is possible to map arbitrary deep object graphs. When mapping from entities into data transfer objects it is often useful to cut references to other entities at a certain point. To do so, implement a custom mapping method (see the next section) which e.g. maps a referenced entity to its id in the target object. + +When generating the implementation of a mapping method, MapStruct will apply the following routine for each attribute pair in the source and target object: + +. If source and target attribute have the same type, the value will be simply copied *direct* from source to target. If the attribute is a collection (e.g. a `List`) a copy of the collection will be set into the target attribute. +. If source and target attribute type differ, check whether there is another *mapping method* which has the type of the source attribute as parameter type and the type of the target attribute as return type. If such a method exists it will be invoked in the generated mapping implementation. +. If no such method exists MapStruct will look whether a *built-in conversion* for the source and target type of the attribute exists. If this is the case, the generated mapping code will apply this conversion. +. If no such method exists MapStruct will apply *complex* conversions: +.. mapping method, the result mapped by mapping method, like this: `target = method1( method2( source ) )` +.. built-in conversion, the result mapped by mapping method, like this: `target = method( conversion( source ) )` +.. mapping method, the result mapped by build-in conversion, like this: `target = conversion( method( source ) )` +. If no such method was found MapStruct will try to generate an automatic sub-mapping method that will do the mapping between the source and target attributes. +. If MapStruct could not create a name based mapping method an error will be raised at build time, indicating the non-mappable attribute and its path. + +A mapping control (`MappingControl`) can be defined on all levels (`@MapperConfig`, `@Mapper`, `@BeanMapping`, `@Mapping`), the latter taking precedence over the former. For example: `@Mapper( mappingControl = NoComplexMapping.class )` takes precedence over `@MapperConfig( mappingControl = DeepClone.class )`. `@IterableMapping` and `@MapMapping` work similar as `@Mapping`. MappingControl is experimental from MapStruct 1.4. +`MappingControl` has an enum that corresponds to the first 4 options above: `MappingControl.Use#DIRECT`, `MappingControl.Use#MAPPING_METHOD`, `MappingControl.Use#BUILT_IN_CONVERSION` and `MappingControl.Use#COMPLEX_MAPPING` the presence of which allows the user to switch *on* a option. The absence of an enum switches *off* a mapping option. Default they are all present enabling all mapping options. + +[NOTE] +==== +In order to stop MapStruct from generating automatic sub-mapping methods as in 5. above, one can use `@Mapper( disableSubMappingMethodsGeneration = true )`. +==== + +[TIP] +==== +The user has full control over the mapping by means of meta annotations. Some handy ones have been defined such as `@DeepClone` which only allows direct mappings. The result: if source and target type are the same, MapStruct will make a deep clone of the source. Sub-mappings-methods have to be allowed (default option). +==== + +[NOTE] +==== +During the generation of automatic sub-mapping methods <> will not be taken into consideration, yet. +Follow issue https://github.com/mapstruct/mapstruct/issues/1086[#1086] for more information. +==== + +[NOTE] +==== +Constructor properties of the target object are also considered as target properties. +You can read more about that in <> +==== + +[[controlling-nested-bean-mappings]] +=== Controlling nested bean mappings + +As explained above, MapStruct will generate a method based on the name of the source and target property. Unfortunately, in many occasions these names do not match. + +The ‘.’ notation in an `@Mapping` source or target type can be used to control how properties should be mapped when names do not match. +There is an elaborate https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-nested-bean-mappings[example] in our examples repository to explain how this problem can be overcome. + +In the simplest scenario there’s a property on a nested level that needs to be corrected. +Take for instance a property `fish` which has an identical name in `FishTankDto` and `FishTank`. +For this property MapStruct automatically generates a mapping: `FishDto fishToFishDto(Fish fish)`. +MapStruct cannot possibly be aware of the deviating properties `kind` and `type`. +Therefore this can be addressed in a mapping rule: `@Mapping(target="fish.kind", source="fish.type")`. +This tells MapStruct to deviate from looking for a name `kind` at this level and map it to `type`. + +.Mapper controlling nested beans mappings I +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface FishTankMapper { + + @Mapping(target = "fish.kind", source = "fish.type") + @Mapping(target = "fish.name", ignore = true) + @Mapping(target = "ornament", source = "interior.ornament") + @Mapping(target = "material.materialType", source = "material") + @Mapping(target = "quality.report.organisation.name", source = "quality.report.organisationName") + FishTankDto map( FishTank source ); +} +---- +==== + +The same constructs can be used to ignore certain properties at a nesting level, as is demonstrated in the second `@Mapping` rule. + +MapStruct can even be used to “cherry pick” properties when source and target do not share the same nesting level (the same number of properties). +This can be done in the source – and in the target type. This is demonstrated in the next 2 rules: `@Mapping(target="ornament", source="interior.ornament")` and `@Mapping(target="material.materialType", source="material")`. + +The latter can even be done when mappings first share a common base. +For example: all properties that share the same name of `Quality` are mapped to `QualityDto`. +Likewise, all properties of `Report` are mapped to `ReportDto`, with one exception: `organisation` in `OrganisationDto` is left empty (since there is no organization at the source level). +Only the `name` is populated with the `organisationName` from `Report`. +This is demonstrated in `@Mapping(target="quality.report.organisation.name", source="quality.report.organisationName")` + +Coming back to the original example: what if `kind` and `type` would be beans themselves? +In that case MapStruct would again generate a method continuing to map. +Such is demonstrated in the next example: + + +.Mapper controlling nested beans mappings II +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface FishTankMapperWithDocument { + + @Mapping(target = "fish.kind", source = "fish.type") + @Mapping(target = "fish.name", expression = "java(\"Jaws\")") + @Mapping(target = "plant", ignore = true ) + @Mapping(target = "ornament", ignore = true ) + @Mapping(target = "material", ignore = true) + @Mapping(target = "quality.document", source = "quality.report") + @Mapping(target = "quality.document.organisation.name", constant = "NoIdeaInc" ) + FishTankWithNestedDocumentDto map( FishTank source ); + +} +---- +==== + +Note what happens in `@Mapping(target="quality.document", source="quality.report")`. +`DocumentDto` does not exist as such on the target side. It is mapped from `Report`. +MapStruct continues to generate mapping code here. That mapping itself can be guided towards another name. +This even works for constants and expression. Which is shown in the final example: `@Mapping(target="quality.document.organisation.name", constant="NoIdeaInc")`. + +MapStruct will perform a null check on each nested property in the source. + +[TIP] +==== +Instead of configuring everything via the parent method we encourage users to explicitly write their own nested methods. +This puts the configuration of the nested mapping into one place (method) where it can be reused from several methods in the upper level, +instead of re-configuring the same things on all of those upper methods. +==== + +[TIP] +==== +When ignoring multiple properties instead of defining multiple `@Mapping` annotations, you can use the `@Ignored` annotation to group them together. +e.g. for the `FishTankMapperWithDocument` example above, you could write: +`@Ignored(targets = { "plant", "ornament", "material" })` +==== + +[NOTE] +==== +In some cases the `ReportingPolicy` that is going to be used for the generated nested method would be `IGNORE`. +This means that it is possible for MapStruct not to report unmapped target properties in nested mappings. +==== + + +[[invoking-custom-mapping-method]] +=== Invoking custom mapping method + +Sometimes mappings are not straightforward and some fields require custom logic. + +The example below demonstrates how the properties `length`, `width` and `height` in `FishTank` can be mapped to the `VolumeDto` bean, which is a member of `FishTankWithVolumeDto`. `VolumeDto` contains the properties `volume` and `description`. Custom logic is achieved by defining a method which takes `FishTank` instance as a parameter and returns a `VolumeDto`. MapStruct will take the entire parameter `source` and generate code to call the custom method `mapVolume` in order to map the `FishTank` object to the target property `volume`. + +The remainder of the fields could be mapped the regular way: using mappings defined defined by means of `@Mapping` annotations. + +.Manually implemented mapping method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class FishTank { + Fish fish; + String material; + Quality quality; + int length; + int width; + int height; +} + +public class FishTankWithVolumeDto { + FishDto fish; + MaterialDto material; + QualityDto quality; + VolumeDto volume; +} + +public class VolumeDto { + int volume; + String description; +} + +@Mapper +public abstract class FishTankMapperWithVolume { + + @Mapping(target = "fish.kind", source = "source.fish.type") + @Mapping(target = "material.materialType", source = "source.material") + @Mapping(target = "quality.document", source = "source.quality.report") + @Mapping(target = "volume", source = "source") + abstract FishTankWithVolumeDto map(FishTank source); + + VolumeDto mapVolume(FishTank source) { + int volume = source.length * source.width * source.height; + String desc = volume < 100 ? "Small" : "Large"; + return new VolumeDto(volume, desc); + } +} +---- +==== + +Note the `@Mapping` annotation where `source` field is equal to `"source"`, indicating the parameter name `source` itself in the method `map(FishTank source)` instead of a (target) property in `FishTank`. + + +[[invoking-other-mappers]] +=== Invoking other mappers + +In addition to methods defined on the same mapper type MapStruct can also invoke mapping methods defined in other classes, be it mappers generated by MapStruct or hand-written mapping methods. This can be useful to structure your mapping code in several classes (e.g. with one mapper type per application module) or if you want to provide custom mapping logic which can't be generated by MapStruct. + +For instance the `Car` class might contain an attribute `manufacturingDate` while the corresponding DTO attribute is of type String. In order to map this attribute, you could implement a mapper class like this: + +.Manually implemented mapper class +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class DateMapper { + + public String asString(Date date) { + return date != null ? new SimpleDateFormat( "yyyy-MM-dd" ) + .format( date ) : null; + } + + public Date asDate(String date) { + try { + return date != null ? new SimpleDateFormat( "yyyy-MM-dd" ) + .parse( date ) : null; + } + catch ( ParseException e ) { + throw new RuntimeException( e ); + } + } +} +---- +==== + +In the `@Mapper` annotation at the `CarMapper` interface reference the `DateMapper` class like this: + +.Referencing another mapper class +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(uses=DateMapper.class) +public interface CarMapper { + + CarDto carToCarDto(Car car); +} +---- +==== + +When generating code for the implementation of the `carToCarDto()` method, MapStruct will look for a method which maps a `Date` object into a String, find it on the `DateMapper` class and generate an invocation of `asString()` for mapping the `manufacturingDate` attribute. + +Generated mappers retrieve referenced mappers using the component model configured for them. If e.g. CDI was used as component model for `CarMapper`, `DateMapper` would have to be a CDI bean as well. When using the default component model, any hand-written mapper classes to be referenced by MapStruct generated mappers must declare a public no-args constructor in order to be instantiable. + +[[passing-target-type]] +=== Passing the mapping target type to custom mappers + +When having a custom mapper hooked into the generated mapper with `@Mapper#uses()`, an additional parameter of type `Class` (or a super-type of it) can be defined in the custom mapping method in order to perform general mapping tasks for specific target object types. That attribute must be annotated with `@TargetType` for MapStruct to generate calls that pass the `Class` instance representing the corresponding property type of the target bean. + +For instance, the `CarDto` could have a property `owner` of type `Reference` that contains the primary key of a `Person` entity. You could now create a generic custom mapper that resolves any `Reference` objects to their corresponding managed JPA entity instances. + +e.g. + +.Example classes for the passing target type example +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Car { + + private Person owner; + // ... +} + +public class Person extends BaseEntity { + + // ... +} + +public class Reference { + + private String pk; + // ... +} + +public class CarDto { + + private Reference owner; + // ... +} +---- +==== + + +.Mapping method expecting mapping target type as parameter +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@ApplicationScoped // CDI component model +public class ReferenceMapper { + + @PersistenceContext + private EntityManager entityManager; + + public T resolve(Reference reference, @TargetType Class entityClass) { + return reference != null ? entityManager.find( entityClass, reference.getPk() ) : null; + } + + public Reference toReference(BaseEntity entity) { + return entity != null ? new Reference( entity.getPk() ) : null; + } +} + +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = ReferenceMapper.class ) +public interface CarMapper { + + Car carDtoToCar(CarDto carDto); +} +---- +==== + +MapStruct will then generate something like this: + +.Generated code +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +@ApplicationScoped +public class CarMapperImpl implements CarMapper { + + @Inject + private ReferenceMapper referenceMapper; + + @Override + public Car carDtoToCar(CarDto carDto) { + if ( carDto == null ) { + return null; + } + + Car car = new Car(); + + car.setOwner( referenceMapper.resolve( carDto.getOwner(), Owner.class ) ); + // ... + + return car; + } +} +---- +==== + +[[passing-context]] +=== Passing context or state objects to custom methods + +Additional _context_ or _state_ information can be passed through generated mapping methods to custom methods with `@Context` parameters. Such parameters are passed to other mapping methods, `@ObjectFactory` methods (see <>) or `@BeforeMapping` / `@AfterMapping` methods (see <>) when applicable and can thus be used in custom code. + +`@Context` parameters are searched for `@ObjectFactory` methods, which are called on the provided context parameter value if applicable. + +`@Context` parameters are also searched for `@BeforeMapping` / `@AfterMapping` methods, which are called on the provided context parameter value if applicable. + +*Note:* no `null` checks are performed before calling before/after mapping methods on context parameters. The caller needs to make sure that `null` is not passed in that case. + +For generated code to call a method that is declared with `@Context` parameters, the declaration of the mapping method being generated needs to contain at least those (or assignable) `@Context` parameters as well. The generated code will not create new instances of missing `@Context` parameters nor will it pass a literal `null` instead. + +.Using `@Context` parameters for passing data down to hand-written property mapping methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public abstract CarDto toCar(Car car, @Context Locale translationLocale); + +protected OwnerManualDto translateOwnerManual(OwnerManual ownerManual, @Context Locale locale) { + // manually implemented logic to translate the OwnerManual with the given Locale +} +---- +==== + +MapStruct will then generate something like this: + +.Generated code +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +public CarDto toCar(Car car, Locale translationLocale) { + if ( car == null ) { + return null; + } + + CarDto carDto = new CarDto(); + + carDto.setOwnerManual( translateOwnerManual( car.getOwnerManual(), translationLocale ); + // more generated mapping code + + return carDto; +} +---- +==== + + +[[mapping-method-resolution]] +=== Mapping method resolution + +When mapping a property from one type to another, MapStruct looks for the most specific method which maps the source type into the target type. The method may either be declared on the same mapper interface or on another mapper which is registered via `@Mapper#uses()`. The same applies for factory methods (see <>). + +The algorithm for finding a mapping or factory method resembles Java's method resolution algorithm as much as possible. In particular, methods with a more specific source type will take precedence (e.g. if there are two methods, one which maps the searched source type, and another one which maps a super-type of the same). In case more than one most-specific method is found, an error will be raised. + +[TIP] +==== +When working with JAXB, e.g. when converting a `String` to a corresponding `JAXBElement`, MapStruct will take the `scope` and `name` attributes of `@XmlElementDecl` annotations into account when looking for a mapping method. This makes sure that the created `JAXBElement` instances will have the right QNAME value. You can find a test which maps JAXB objects https://github.com/mapstruct/mapstruct/blob/{mapstructVersion}/integrationtest/src/test/resources/jaxbTest/src/test/java/org/mapstruct/itest/jaxb/JaxbBasedMapperTest.java[here]. +==== + +[[selection-based-on-qualifiers]] +=== Mapping method selection based on qualifiers + +In many occasions one requires mapping methods with the same method signature (apart from the name) that have different behavior. +MapStruct has a handy mechanism to deal with such situations: `@Qualifier` (`org.mapstruct.Qualifier`). +A ‘qualifier’ is a custom annotation that the user can write, ‘stick onto’ a mapping method which is included as used mapper +and can be referred to in a bean property mapping, iterable mapping or map mapping. +Multiple qualifiers can be ‘stuck onto’ a method and mapping. + +So, let's say there is a hand-written method to map titles with a `String` return type and `String` argument amongst many other referenced mappers with the same `String` return type - `String` argument signature: + +.Several mapping methods with identical source and target types +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class Titles { + + public String translateTitleEG(String title) { + // some mapping logic + } + + public String translateTitleGE(String title) { + // some mapping logic + } +} +---- +==== + +And a mapper using this handwritten mapper, in which source and target have a property 'title' that should be mapped: + +.Mapper causing an ambiguous mapping method error +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper( uses = Titles.class ) +public interface MovieMapper { + + GermanRelease toGerman( OriginalRelease movies ); + +} +---- +==== + +Without the use of qualifiers, this would result in an ambiguous mapping method error, because 2 qualifying methods are found (`translateTitleEG`, `translateTitleGE`) and MapStruct would not have a hint which one to choose. + +Enter the qualifier approach: + +.Declaring a qualifier type +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +import org.mapstruct.Qualifier; + +@Qualifier +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.CLASS) +public @interface TitleTranslator { +} +---- +==== + +And, some qualifiers to indicate which translator to use to map from source language to target language: + +.Declaring qualifier types for mapping methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +import org.mapstruct.Qualifier; + +@Qualifier +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface EnglishToGerman { +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +import org.mapstruct.Qualifier; + +@Qualifier +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.CLASS) +public @interface GermanToEnglish { +} +---- +==== + +Please take note of the target `TitleTranslator` on type level, `EnglishToGerman`, `GermanToEnglish` on method level! + +Then, using the qualifiers, the mapping could look like this: + +.Mapper using qualifiers +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper( uses = Titles.class ) +public interface MovieMapper { + + @Mapping( target = "title", qualifiedBy = { TitleTranslator.class, EnglishToGerman.class } ) + GermanRelease toGerman( OriginalRelease movies ); + +} +---- +==== + +.Custom mapper qualifying the methods it provides +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@TitleTranslator +public class Titles { + + @EnglishToGerman + public String translateTitleEG(String title) { + // some mapping logic + } + + @GermanToEnglish + public String translateTitleGE(String title) { + // some mapping logic + } +} +---- +==== + +[WARNING] +==== +Please make sure the used retention policy equals retention policy `CLASS` (`@Retention(RetentionPolicy.CLASS)`). +==== + +[WARNING] +==== +A class / method annotated with a qualifier will not qualify anymore for mappings that do not have the `qualifiedBy` element. +==== + +[TIP] +==== +The same mechanism is also present on bean mappings: `@BeanMapping#qualifiedBy`: it selects the factory method marked with the indicated qualifier. +==== + +In many occasions, declaring a new annotation to aid the selection process can be too much for what you try to achieve. For those situations, MapStruct has the `@Named` annotation. This annotation is a pre-defined qualifier (annotated with `@Qualifier` itself) and can be used to name a Mapper or, more directly a mapping method by means of its value. The same example above would look like: + +.Custom mapper, annotating the methods to qualify by means of `@Named` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Named("TitleTranslator") +public class Titles { + + @Named("EnglishToGerman") + public String translateTitleEG(String title) { + // some mapping logic + } + + @Named("GermanToEnglish") + public String translateTitleGE(String title) { + // some mapping logic + } +} +---- +==== + +.Mapper using named +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper( uses = Titles.class ) +public interface MovieMapper { + + @Mapping( target = "title", qualifiedByName = { "TitleTranslator", "EnglishToGerman" } ) + GermanRelease toGerman( OriginalRelease movies ); + +} +---- +==== + +[WARNING] +==== +Although the used mechanism is the same, the user has to be a bit more careful. Refactoring the name of a defined qualifier in an IDE will neatly refactor all other occurrences as well. This is obviously not the case for changing a name. +==== + +=== Combining qualifiers with defaults +Please note that the `Mapping#defaultValue` is in essence a `String`, which needs to be converted to the `Mapping#target`. Providing a `Mapping#qualifiedByName` or `Mapping#qualifiedBy` will force MapStruct to use that method. If you want different behavior for the `Mapping#defaultValue`, then please provide an appropriate mapping method. This mapping method needs to transforms a `String` into the desired type of `Mapping#target` and also be annotated so that it can be found by the `Mapping#qualifiedByName` or `Mapping#qualifiedBy`. + +.Mapper using defaultValue +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface MovieMapper { + + @Mapping( target = "category", qualifiedByName = "CategoryToString", defaultValue = "DEFAULT" ) + GermanRelease toGerman( OriginalRelease movies ); + + @Named("CategoryToString") + default String defaultValueForQualifier(Category cat) { + // some mapping logic + } +} +---- +==== + +In the above example in case that category is null, the method `CategoryToString( Enum.valueOf( Category.class, "DEFAULT" ) )` will be called and the result will be set to the category field. + +.Mapper using defaultValue and default method. +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface MovieMapper { + + @Mapping( target = "category", qualifiedByName = "CategoryToString", defaultValue = "Unknown" ) + GermanRelease toGerman( OriginalRelease movies ); + + @Named("CategoryToString") + default String defaultValueForQualifier(Category cat) { + // some mapping logic + } + + @Named("CategoryToString") + default String defaultValueForQualifier(String value) { + return value; + } +} +---- +==== +In the above example in case that category is null, the method `defaultValueForQualifier( "Unknown" )` will be called and the result will be set to the category field. + +If the above mentioned methods do not work there is the option to use `defaultExpression` to set the default value. + +.Mapper using defaultExpression +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface MovieMapper { + + @Mapping( target = "category", qualifiedByName = "CategoryToString", defaultExpression = "java(\"Unknown\")" ) + GermanRelease toGerman( OriginalRelease movies ); + + @Named("CategoryToString") + default String defaultValueForQualifier(Category cat) { + // some mapping logic + } +} +---- +==== diff --git a/documentation/src/main/asciidoc/chapter-6-mapping-collections.asciidoc b/documentation/src/main/asciidoc/chapter-6-mapping-collections.asciidoc new file mode 100644 index 0000000000..4510c82cc0 --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-6-mapping-collections.asciidoc @@ -0,0 +1,231 @@ +[[mapping-collections]] +== Mapping collections + +The mapping of collection types (`List`, `Set` etc.) is done in the same way as mapping bean types, i.e. by defining mapping methods with the required source and target types in a mapper interface. MapStruct supports a wide range of iterable types from the http://docs.oracle.com/javase/tutorial/collections/intro/index.html[Java Collection Framework]. + +The generated code will contain a loop which iterates over the source collection, converts each element and puts it into the target collection. If a mapping method for the collection element types is found in the given mapper or the mapper it uses, this method is invoked to perform the element conversion. Alternatively, if an implicit conversion for the source and target element types exists, this conversion routine will be invoked. The following shows an example: + +.Mapper with collection mapping methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + Set integerSetToStringSet(Set integers); + + List carsToCarDtos(List cars); + + CarDto carToCarDto(Car car); +} +---- +==== + +The generated implementation of the `integerSetToStringSet` performs the conversion from `Integer` to `String` for each element, while the generated `carsToCarDtos()` method invokes the `carToCarDto()` method for each contained element as shown in the following: + +.Generated collection mapping methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +@Override +public Set integerSetToStringSet(Set integers) { + if ( integers == null ) { + return null; + } + + Set set = new LinkedHashSet(); + + for ( Integer integer : integers ) { + set.add( String.valueOf( integer ) ); + } + + return set; +} + +@Override +public List carsToCarDtos(List cars) { + if ( cars == null ) { + return null; + } + + List list = new ArrayList(); + + for ( Car car : cars ) { + list.add( carToCarDto( car ) ); + } + + return list; +} +---- +==== + +Note that MapStruct will look for a collection mapping method with matching parameter and return type, when mapping a collection-typed attribute of a bean, e.g. from `Car#passengers` (of type `List`) to `CarDto#passengers` (of type `List`). + +.Usage of collection mapping method to map a bean property +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +carDto.setPassengers( personsToPersonDtos( car.getPassengers() ) ); +... +---- +==== + +Some frameworks and libraries only expose JavaBeans getters but no setters for collection-typed properties. Types generated from an XML schema using JAXB adhere to this pattern by default. In this case the generated code for mapping such a property invokes its getter and adds all the mapped elements: + +.Usage of an adding method for collection mapping +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +carDto.getPassengers().addAll( personsToPersonDtos( car.getPassengers() ) ); +... +---- +==== + +[WARNING] +==== +It is not allowed to declare mapping methods with an iterable source (from a java package) and a non-iterable target or the other way around. An error will be raised when detecting this situation. +==== + +[[mapping-maps]] +=== Mapping maps + +Also map-based mapping methods are supported. The following shows an example: + +.Map mapping method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public interface SourceTargetMapper { + + @MapMapping(valueDateFormat = "dd.MM.yyyy") + Map longDateMapToStringStringMap(Map source); +} +---- +==== + +Similar to iterable mappings, the generated code will iterate through the source map, convert each value and key (either by means of an implicit conversion or by invoking another mapping method) and put them into the target map: + +.Generated implementation of map mapping method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +@Override +public Map stringStringMapToLongDateMap(Map source) { + if ( source == null ) { + return null; + } + + Map map = new LinkedHashMap(); + + for ( Map.Entry entry : source.entrySet() ) { + + Long key = Long.parseLong( entry.getKey() ); + Date value; + try { + value = new SimpleDateFormat( "dd.MM.yyyy" ).parse( entry.getValue() ); + } + catch( ParseException e ) { + throw new RuntimeException( e ); + } + + map.put( key, value ); + } + + return map; +} +---- +==== + +[[collection-mapping-strategies]] +=== Collection mapping strategies + +MapStruct has a `CollectionMappingStrategy`, with the possible values: `ACCESSOR_ONLY`, `SETTER_PREFERRED`, `ADDER_PREFERRED` and `TARGET_IMMUTABLE`. + +In the table below, the dash `-` indicates a property name. Next, the trailing `s` indicates the plural form. The table explains the options and how they are applied to the presence/absence of a `set-s`, `add-` and / or `get-s` method on the target object: + +.Collection mapping strategy options +|=== +|Option|Only target set-s Available|Only target add- Available|Both set-s / add- Available|No set-s / add- Available|Existing Target(`@TargetType`) + +|`ACCESSOR_ONLY` +|set-s +|get-s +|set-s +|get-s +|get-s + +|`SETTER_PREFERRED` +|set-s +|add- +|set-s +|get-s +|get-s + +|`ADDER_PREFERRED` +|set-s +|add- +|add- +|get-s +|get-s + +|`TARGET_IMMUTABLE` +|set-s +|exception +|set-s +|exception +|set-s +|=== + +Some background: An `adder` method is typically used in case of http://www.eclipse.org/webtools/dali/[generated (JPA) entities], to add a single element (entity) to an underlying collection. Invoking the adder establishes a parent-child relation between parent - the bean (entity) on which the adder is invoked - and its child(ren), the elements (entities) in the collection. To find the appropriate `adder`, MapStruct will try to make a match between the generic parameter type of the underlying collection and the single argument of a candidate `adder`. When there are more candidates, the plural `setter` / `getter` name is converted to singular and will be used in addition to make a match. + +The option `DEFAULT` should not be used explicitly. It is used to distinguish between an explicit user desire to override the default in a `@MapperConfig` from the implicit Mapstruct choice in a `@Mapper`. The option `DEFAULT` is synonymous to `ACCESSOR_ONLY`. + +[TIP] +==== +When working with an `adder` method and JPA entities, Mapstruct assumes that the target collections are initialized with a collection implementation (e.g. an `ArrayList`). You can use factories to create a new target entity with initialized collections instead of Mapstruct creating the target entity by its constructor. +==== + +[[implementation-types-for-collection-mappings]] +=== Implementation types used for collection mappings + +When an iterable or map mapping method declares an interface type as return type, one of its implementation types will be instantiated in the generated code. The following table shows the supported interface types and their corresponding implementation types as instantiated in the generated code: + +.Collection mapping implementation types +|=== +|Interface type|Implementation type + +|`Iterable`|`ArrayList` + +|`Collection`|`ArrayList` + +|`List`|`ArrayList` + +|`Set`|`LinkedHashSet` + +|`SequencedSet`|`LinkedHashSet` + +|`SortedSet`|`TreeSet` + +|`NavigableSet`|`TreeSet` + +|`Map`|`LinkedHashMap` + +|`SequencedMap`|`LinkedHashMap` + +|`SortedMap`|`TreeMap` + +|`NavigableMap`|`TreeMap` + +|`ConcurrentMap`|`ConcurrentHashMap` +|`ConcurrentNavigableMap`|`ConcurrentSkipListMap` +|=== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/chapter-7-mapping-streams.asciidoc b/documentation/src/main/asciidoc/chapter-7-mapping-streams.asciidoc new file mode 100644 index 0000000000..ec41719eb8 --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-7-mapping-streams.asciidoc @@ -0,0 +1,67 @@ +[[mapping-streams]] +== Mapping Streams + +The mapping of `java.util.Stream` is done in a similar way as the mapping of collection types, i.e. by defining mapping +methods with the required source and target types in a mapper interface. + +The generated code will contain the creation of a `Stream` from the provided `Iterable`/array or will collect the +provided `Stream` into an `Iterable`/array. If a mapping method or an implicit conversion for the source and target +element types exists, then this conversion will be done in `Stream#map()`. The following shows an example: + +.Mapper with stream mapping methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CarMapper { + + Set integerStreamToStringSet(Stream integers); + + List carsToCarDtos(Stream cars); + + CarDto carToCarDto(Car car); +} +---- +==== + +The generated implementation of the `integerStreamToStringSet()` performs the conversion from `Integer` to `String` for +each element, while the generated `carsToCarDtos()` method invokes the `carToCarDto()` method for each contained +element as shown in the following: + +.Generated stream mapping methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +@Override +public Set integerStreamToStringSet(Stream integers) { + if ( integers == null ) { + return null; + } + + return integers.map( integer -> String.valueOf( integer ) ) + .collect( Collectors.toCollection( LinkedHashSet::new ) ); +} + +@Override +public List carsToCarDtos(Stream cars) { + if ( cars == null ) { + return null; + } + + return cars.map( car -> carToCarDto( car ) ) + .collect( Collectors.toCollection( ArrayList::new ) ); +} +---- +==== + +[WARNING] +==== +If a mapping from a `Stream` to an `Iterable` or an array is performed, then the passed `Stream` will be consumed +and it will no longer be possible to consume it. +==== + +The same implementation types as in <> are used for the creation of the +collection when doing `Stream` to `Iterable` mapping. diff --git a/documentation/src/main/asciidoc/chapter-8-mapping-values.asciidoc b/documentation/src/main/asciidoc/chapter-8-mapping-values.asciidoc new file mode 100644 index 0000000000..fcb353010d --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-8-mapping-values.asciidoc @@ -0,0 +1,356 @@ +[[mapping-enum-types]] +== Mapping Values + +=== Mapping enum to enum types + +MapStruct supports the generation of methods which map one Java enum type into another. + +By default, each constant from the source enum is mapped to a constant with the same name in the target enum type. If required, a constant from the source enum may be mapped to a constant with another name with help of the `@ValueMapping` annotation. Several constants from the source enum can be mapped to the same constant in the target type. + +The following shows an example: + +.Enum mapping method +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface OrderMapper { + + OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class ); + + @ValueMappings({ + @ValueMapping(target = "SPECIAL", source = "EXTRA"), + @ValueMapping(target = "DEFAULT", source = "STANDARD"), + @ValueMapping(target = "DEFAULT", source = "NORMAL") + }) + ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); +} +---- +==== + +.Enum mapping method result +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class OrderMapperImpl implements OrderMapper { + + @Override + public ExternalOrderType orderTypeToExternalOrderType(OrderType orderType) { + if ( orderType == null ) { + return null; + } + + ExternalOrderType externalOrderType_; + + switch ( orderType ) { + case EXTRA: externalOrderType_ = ExternalOrderType.SPECIAL; + break; + case STANDARD: externalOrderType_ = ExternalOrderType.DEFAULT; + break; + case NORMAL: externalOrderType_ = ExternalOrderType.DEFAULT; + break; + case RETAIL: externalOrderType_ = ExternalOrderType.RETAIL; + break; + case B2B: externalOrderType_ = ExternalOrderType.B2B; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + orderType ); + } + + return externalOrderType_; + } +} +---- +==== +By default an error will be raised by MapStruct in case a constant of the source enum type does not have a corresponding constant with the same name in the target type and also is not mapped to another constant via `@ValueMapping`. This ensures that all constants are mapped in a safe and predictable manner. The generated +mapping method will throw an `IllegalStateException` if for some reason an unrecognized source value occurs. + +MapStruct also has a mechanism for mapping any remaining (unspecified) mappings to a default. This can be used only once in a set of value mappings and only applies to the source. It comes in two flavors: `` and ``. They cannot be used at the same time. + +In case of source `` MapStruct will continue to map a source enum constant to a target enum constant with the same name. The remainder of the source enum constants will be mapped to the target specified in the `@ValueMapping` with `` source. + +MapStruct will *not* attempt such name based mapping for `` and directly apply the target specified in the `@ValueMapping` with `` source to the remainder. + +MapStruct is able to handle `null` sources and `null` targets by means of the `` keyword. + +In addition, the constant value `` can be used for throwing an exception for particular value mappings. This value is only applicable to `ValueMapping#target()` and not `ValueMapping#source()` since MapStruct can't map from exceptions. + +[TIP] +==== +Constants for ``, ``, `` and `` are available in the `MappingConstants` class. +==== + +Finally `@InheritInverseConfiguration` and `@InheritConfiguration` can be used in combination with `@ValueMappings`. `` and `` will be ignored in that case. + +The following code snippets exemplify the use of the aforementioned constants. + +.Enum mapping method, `` and `` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface SpecialOrderMapper { + + SpecialOrderMapper INSTANCE = Mappers.getMapper( SpecialOrderMapper.class ); + + @ValueMappings({ + @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ), + @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ), + @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" ) + }) + ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); +} +---- +==== + +.Enum mapping method result, `` and `` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class SpecialOrderMapperImpl implements SpecialOrderMapper { + + @Override + public ExternalOrderType orderTypeToExternalOrderType(OrderType orderType) { + if ( orderType == null ) { + return ExternalOrderType.DEFAULT; + } + + ExternalOrderType externalOrderType_; + + switch ( orderType ) { + case STANDARD: externalOrderType_ = null; + break; + case RETAIL: externalOrderType_ = ExternalOrderType.RETAIL; + break; + case B2B: externalOrderType_ = ExternalOrderType.B2B; + break; + default: externalOrderType_ = ExternalOrderType.SPECIAL; + } + + return externalOrderType_; + } +} +---- +==== + +*Note:* MapStruct would have refrained from mapping the `RETAIL` and `B2B` when `` was used instead of ``. + + +.Enum mapping method with `` +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface SpecialOrderMapper { + + SpecialOrderMapper INSTANCE = Mappers.getMapper( SpecialOrderMapper.class ); + + @ValueMappings({ + @ValueMapping( source = "STANDARD", target = "DEFAULT" ), + @ValueMapping( source = "C2C", target = MappingConstants.THROW_EXCEPTION ) + }) + ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); +} +---- +==== + +.Enum mapping method with `` result +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class SpecialOrderMapperImpl implements SpecialOrderMapper { + + @Override + public ExternalOrderType orderTypeToExternalOrderType(OrderType orderType) { + if ( orderType == null ) { + return null; + } + + ExternalOrderType externalOrderType; + + switch ( orderType ) { + case STANDARD: externalOrderType = ExternalOrderType.DEFAULT; + break; + case C2C: throw new IllegalArgumentException( "Unexpected enum constant: " + orderType ); + default: throw new IllegalArgumentException( "Unexpected enum constant: " + orderType ); + } + + return externalOrderType; + } +} +---- +==== + +=== Mapping enum-to-String or String-to-enum + +MapStruct supports enum to a String mapping along the same lines as is described in <>. There are similarities and differences: + +*enum to `String`* + +1. Similarity: All not explicit defined mappings will result in each source enum constant value being mapped a `String` value with the same constant value. +2. Similarity: ` stops after handling defined mapping and proceeds to the switch/default clause value. +3. Difference: `` will result in an error. It acts on the premise that there is name similarity between enum constants in source and target which does not make sense for a String type. +4. Difference: Given 1. and 3. there will never be unmapped values. +5. Similarity: `` can be used for throwing an exception for particular enum values. + +*`String` to enum* + +1. Similarity: All not explicit defined mappings will result in the target enum constant mapped from the `String` value when that matches the target enum constant name. +2. Similarity: ` stops after handling defined mapping and proceeds to the switch/default clause value. +3. Similarity: `` will create a mapping for each target enum constant and proceed to the switch/default clause value. +4. Difference: A switch/default value needs to be provided to have a determined outcome (enum has a limited set of values, `String` has unlimited options). Failing to specify `` or ` will result in a warning. +5. Similarity: `` can be used for throwing an exception for any arbitrary `String` value. + +=== Custom name transformation + +When no `@ValueMapping`(s) are defined then each constant from the source enum is mapped to a constant with the same name in the target enum type. +However, there are cases where the source enum needs to be transformed before doing the mapping. +E.g. a suffix needs to be applied to map from the source into the target enum. + +.Enum types +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public enum CheeseType { + + BRIE, + ROQUEFORT +} + +public enum CheeseTypeSuffixed { + + BRIE_TYPE, + ROQUEFORT_TYPE +} +---- +==== + +.Enum mapping method with custom name transformation strategy +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface CheeseMapper { + + CheeseMapper INSTANCE = Mappers.getMapper( CheeseMapper.class ); + + @EnumMapping(nameTransformationStrategy = "suffix", configuration = "_TYPE") + CheeseTypeSuffixed map(CheeseType cheese); + + @InheritInverseConfiguration + CheeseType map(CheeseTypeSuffix cheese); +} +---- +==== + +.Enum mapping method with custom name transformation strategy result +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +// GENERATED CODE +public class CheeseSuffixMapperImpl implements CheeseSuffixMapper { + + @Override + public CheeseTypeSuffixed map(CheeseType cheese) { + if ( cheese == null ) { + return null; + } + + CheeseTypeSuffixed cheeseTypeSuffixed; + + switch ( cheese ) { + case BRIE: cheeseTypeSuffixed = CheeseTypeSuffixed.BRIE_TYPE; + break; + case ROQUEFORT: cheeseTypeSuffixed = CheeseTypeSuffixed.ROQUEFORT_TYPE; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheese ); + } + + return cheeseTypeSuffixed; + } + + @Override + public CheeseType map(CheeseTypeSuffixed cheese) { + if ( cheese == null ) { + return null; + } + + CheeseType cheeseType; + + switch ( cheese ) { + case BRIE_TYPE: cheeseType = CheeseType.BRIE; + break; + case ROQUEFORT_TYPE: cheeseType = CheeseType.ROQUEFORT; + break; + default: throw new IllegalArgumentException( "Unexpected enum constant: " + cheese ); + } + + return cheeseType; + } +} +---- +==== + +MapStruct provides the following out of the box enum name transformation strategies: + +* _suffix_ - Applies a suffix on the source enum +* _stripSuffix_ - Strips a suffix from the source enum +* _prefix_ - Applies a prefix on the source enum +* _stripPrefix_ - Strips a prefix from the source enum +* _case_ - Applies case transformation to the source enum. Supported _case_ transformations are: +** _upper_ - Performs upper case transformation to the source enum +** _lower_ - Performs lower case transformation to the source enum +** _capital_ - Performs capitalisation of the first character of every word in the source enum and everything else to lowercase. A word is split by "_" + +It is also possible to register custom strategies. +For more information on how to do that have a look at <> + +[[value-mapping-composition]] +=== ValueMapping Composition + +The `@ValueMapping` annotation supports now `@Target` with `ElementType#ANNOTATION_TYPE` in addition to `ElementType#METHOD`. +This allows `@ValueMapping` to be used on other (user defined) annotations for re-use purposes. +For example: + +.Custom value mapping annotations +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Retention( RetentionPolicy.CLASS ) +@ValueMapping(source = "EXTRA", target = "SPECIAL") +@ValueMapping(source = MappingConstants.ANY_REMAINING, target = "DEFAULT") +public @interface CustomValueAnnotation { +} +---- +==== +It can be used to describe some common value mapping relationships to avoid duplicate declarations, as in the following example: + +.Using custom combination annotations +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper +public interface ValueMappingCompositionMapper { + + @CustomValueAnnotation + ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); + + @CustomValueAnnotation + @ValueMapping(source = "STANDARD", target = "SPECIAL") + ExternalOrderType duplicateAnnotation(OrderType orderType); +} +---- +==== diff --git a/documentation/src/main/asciidoc/chapter-9-object-factories.asciidoc b/documentation/src/main/asciidoc/chapter-9-object-factories.asciidoc new file mode 100644 index 0000000000..1b1e94c64f --- /dev/null +++ b/documentation/src/main/asciidoc/chapter-9-object-factories.asciidoc @@ -0,0 +1,170 @@ +[[object-factories]] +== Object factories + +By default, the generated code for mapping one bean type into another or updating a bean will call the default constructor to instantiate the target type. + +Alternatively you can plug in custom object factories which will be invoked to obtain instances of the target type. One use case for this is JAXB which creates `ObjectFactory` classes for obtaining new instances of schema types. + +To make use of custom factories register them via `@Mapper#uses()` as described in <>, or implement them directly in your mapper. When creating the target object of a bean mapping, MapStruct will look for a parameterless method, a method annotated with `@ObjectFactory`, or a method with only one `@TargetType` parameter that returns the required target type and invoke this method instead of calling the default constructor: + +.Custom object factories +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class DtoFactory { + + public CarDto createCarDto() { + return // ... custom factory logic + } +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class EntityFactory { + + public T createEntity(@TargetType Class entityClass) { + return // ... custom factory logic + } +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(uses= { DtoFactory.class, EntityFactory.class } ) +public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + CarDto carToCarDto(Car car); + + Car carDtoToCar(CarDto carDto); +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +public class CarMapperImpl implements CarMapper { + + private final DtoFactory dtoFactory = new DtoFactory(); + + private final EntityFactory entityFactory = new EntityFactory(); + + @Override + public CarDto carToCarDto(Car car) { + if ( car == null ) { + return null; + } + + CarDto carDto = dtoFactory.createCarDto(); + + //map properties... + + return carDto; + } + + @Override + public Car carDtoToCar(CarDto carDto) { + if ( carDto == null ) { + return null; + } + + Car car = entityFactory.createEntity( Car.class ); + + //map properties... + + return car; + } +} +---- +==== + +.Custom object factories with update methods +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +@Mapper(uses = { DtoFactory.class, EntityFactory.class, CarMapper.class } ) +public interface OwnerMapper { + + OwnerMapper INSTANCE = Mappers.getMapper( OwnerMapper.class ); + + void updateOwnerDto(Owner owner, @MappingTarget OwnerDto ownerDto); + + void updateOwner(OwnerDto ownerDto, @MappingTarget Owner owner); +} +---- +[source, java, linenums] +[subs="verbatim,attributes"] +---- +//GENERATED CODE +public class OwnerMapperImpl implements OwnerMapper { + + private final DtoFactory dtoFactory = new DtoFactory(); + + private final EntityFactory entityFactory = new EntityFactory(); + + private final OwnerMapper ownerMapper = Mappers.getMapper( OwnerMapper.class ); + + @Override + public void updateOwnerDto(Owner owner, @MappingTarget OwnerDto ownerDto) { + if ( owner == null ) { + return; + } + + if ( owner.getCar() != null ) { + if ( ownerDto.getCar() == null ) { + ownerDto.setCar( dtoFactory.createCarDto() ); + } + // update car within ownerDto + } + else { + ownerDto.setCar( null ); + } + + // updating other properties + } + + @Override + public void updateOwner(OwnerDto ownerDto, @MappingTarget Owner owner) { + if ( ownerDto == null ) { + return; + } + + if ( ownerDto.getCar() != null ) { + if ( owner.getCar() == null ) { + owner.setCar( entityFactory.createEntity( Car.class ) ); + } + // update car within owner + } + else { + owner.setCar( null ); + } + + // updating other properties + } +} +---- +==== + +In addition, annotating a factory method with `@ObjectFactory` lets you gain access to the mapping sources. +Source objects can be added as parameters in the same way as for mapping method. The `@ObjectFactory` +annotation is necessary to let MapStruct know that the given method is only a factory method. + +.Custom object factories with `@ObjectFactory` + +==== +[source, java, linenums] +[subs="verbatim,attributes"] +---- +public class DtoFactory { + + @ObjectFactory + public CarDto createCarDto(Car car) { + return // ... custom factory logic + } +} +---- +==== \ No newline at end of file diff --git a/documentation/src/main/asciidoc/controlling-nested-bean-mappings.asciidoc b/documentation/src/main/asciidoc/controlling-nested-bean-mappings.asciidoc deleted file mode 100644 index 18e9f54998..0000000000 --- a/documentation/src/main/asciidoc/controlling-nested-bean-mappings.asciidoc +++ /dev/null @@ -1,93 +0,0 @@ -[[controlling-nested-bean-mappings]] -=== Controlling nested bean mappings - -As explained above, MapStruct will generate a method based on the name of the source and target property. Unfortunately, in many occasions these names do not match. - -The ‘.’ notation in an `@Mapping` source or target type can be used to control how properties should be mapped when names do not match. -There is an elaborate https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-nested-bean-mappings[example] in our examples repository to explain how this problem can be overcome. - -In the simplest scenario there’s a property on a nested level that needs to be corrected. -Take for instance a property `fish` which has an identical name in `FishTankDto` and `FishTank`. -For this property MapStruct automatically generates a mapping: `FishDto fishToFishDto(Fish fish)`. -MapStruct cannot possibly be aware of the deviating properties `kind` and `type`. -Therefore this can be addressed in a mapping rule: `@Mapping(target="fish.kind", source="fish.type")`. -This tells MapStruct to deviate from looking for a name `kind` at this level and map it to `type`. - -.Mapper controlling nested beans mappings I -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface FishTankMapper { - - @Mappings({ - @Mapping(target = "fish.kind", source = "fish.type"), - @Mapping(target = "fish.name", ignore = true), - @Mapping(target = "ornament", source = "interior.ornament"), - @Mapping(target = "material.materialType", source = "material"), - @Mapping(target = "quality.report.organisation.name", source = "quality.report.organisationName") - }) - FishTankDto map( FishTank source ); -} ----- -==== - -The same constructs can be used to ignore certain properties at a nesting level, as is demonstrated in the second `@Mapping` rule. - -MapStruct can even be used to “cherry pick” properties when source and target do not share the same nesting level (the same number of properties). -This can be done in the source – and in the target type. This is demonstrated in the next 2 rules: `@Mapping(target="ornament", source="interior.ornament")` and `@Mapping(target="material.materialType", source="material")`. - -The latter can even be done when mappings first share a common base. -For example: all properties that share the same name of `Quality` are mapped to `QualityDto`. -Likewise, all properties of `Report` are mapped to `ReportDto`, with one exception: `organisation` in `OrganisationDto` is left empty (since there is no organization at the source level). -Only the `name` is populated with the `organisationName` from `Report`. -This is demonstrated in `@Mapping(target="quality.report.organisation.name", source="quality.report.organisationName")` - -Coming back to the original example: what if `kind` and `type` would be beans themselves? -In that case MapStruct would again generate a method continuing to map. -Such is demonstrated in the next example: - - -.Mapper controlling nested beans mappings II -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface FishTankMapperWithDocument { - - @Mappings({ - @Mapping(target = "fish.kind", source = "fish.type"), - @Mapping(target = "fish.name", expression = "java(\"Jaws\")"), - @Mapping(target = "plant", ignore = true ), - @Mapping(target = "ornament", ignore = true ), - @Mapping(target = "material", ignore = true), - @Mapping(target = "quality.document", source = "quality.report"), - @Mapping(target = "quality.document.organisation.name", constant = "NoIdeaInc" ) - }) - FishTankWithNestedDocumentDto map( FishTank source ); - -} ----- -==== - -Note what happens in `@Mapping(target="quality.document", source="quality.report")`. -`DocumentDto` does not exist as such on the target side. It is mapped from `Report`. -MapStruct continues to generate mapping code here. That mapping itself can be guided towards another name. -This even works for constants and expression. Which is shown in the final example: `@Mapping(target="quality.document.organisation.name", constant="NoIdeaInc")`. - -MapStruct will perform a null check on each nested property in the source. - -[TIP] -==== -Instead of configuring everything via the parent method we encourage users to explicitly write their own nested methods. -This puts the configuration of the nested mapping into one place (method) where it can be reused from several methods in the upper level, -instead of re-configuring the same things on all of those upper methods. -==== - -[NOTE] -==== -In some cases the `ReportingPolicy` that is going to be used for the generated nested method would be `IGNORE`. -This means that it is possible for MapStruct not to report unmapped target properties in nested mappings. -==== diff --git a/documentation/src/main/asciidoc/mapping-streams.asciidoc b/documentation/src/main/asciidoc/mapping-streams.asciidoc deleted file mode 100644 index a52a569c0c..0000000000 --- a/documentation/src/main/asciidoc/mapping-streams.asciidoc +++ /dev/null @@ -1,67 +0,0 @@ -[[mapping-streams]] -== Mapping Streams - -The mapping of `java.util.Stream` is done in a similar way as the mapping of collection types, i.e. by defining mapping -methods with the required source and target types in a mapper interface. - -The generated code will contain the creation of a `Stream` from the provided `Iterable`/array or will collect the -provided `Stream` into an `Iterable`/array. If a mapping method or an implicit conversion for the source and target -element types exists, then this conversion will be done in `Stream#map()`. The following shows an example: - -.Mapper with stream mapping methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - Set integerStreamToStringSet(Stream integers); - - List carsToCarDtos(Stream cars); - - CarDto carToCarDto(Car car); -} ----- -==== - -The generated implementation of the `integerStreamToStringSet()` performs the conversion from `Integer` to `String` for -each element, while the generated `carsToCarDtos()` method invokes the `carToCarDto()` method for each contained -element as shown in the following: - -.Generated stream mapping methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -@Override -public Set integerStreamToStringSet(Stream integers) { - if ( integers == null ) { - return null; - } - - return integers.stream().map( integer -> String.valueOf( integer ) ) - .collect( Collectors.toCollection( HashSet::new ) ); -} - -@Override -public List carsToCarDtos(Stream cars) { - if ( cars == null ) { - return null; - } - - return integers.stream().map( car -> carToCarDto( car ) ) - .collect( Collectors.toCollection( ArrayList::new ) ); -} ----- -==== - -[WARNING] -==== -If a mapping from a `Stream` to an `Iterable` or an array is performed, then the passed `Stream` will be consumed -and it will no longer be possible to consume it. -==== - -The same implementation types as in <> are used for the creation of the -collection when doing `Stream` to `Iterable` mapping. diff --git a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc index 1620564d1c..1705ed4af1 100644 --- a/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc +++ b/documentation/src/main/asciidoc/mapstruct-reference-guide.asciidoc @@ -2,6 +2,7 @@ :revdate: {docdate} :toc: right :sectanchors: +:source-highlighter: coderay :Author: Gunnar Morling, Andreas Gudian, Sjaak Derksen, Filip Hrisafov and the MapStruct community :processor-dir: ../../../../processor :processor-ap-test: {processor-dir}/src/test/java/org/mapstruct/ap/test @@ -11,7 +12,7 @@ [[Preface]] == Preface This is the reference documentation of MapStruct, an annotation processor for generating type-safe, performant and dependency-free bean mapping code. -This guide covers all the functionality provided by MapStruct. In case this guide doesn't answer all your questions just join the MapStruct https://groups.google.com/forum/?fromgroups#!forum/mapstruct-users[Google group] to get help. +This guide covers all the functionality provided by MapStruct. In case this guide doesn't answer all your questions just join the MapStruct https://github.com/mapstruct/mapstruct/discussions[GitHub Discussions] to get help. You found a typo or other error in this guide? Please let us know by opening an issue in the https://github.com/mapstruct/mapstruct[MapStruct GitHub repository], or, better yet, help the community and send a pull request for fixing it! @@ -20,2818 +21,30 @@ This work is licensed under the http://creativecommons.org/licenses/by-sa/4.0/[C :numbered: -[[introduction]] -== Introduction +include::chapter-1-introduction.asciidoc[] -MapStruct is a Java http://docs.oracle.com/javase/6/docs/technotes/guides/apt/index.html[annotation processor] for the generation of type-safe bean mapping classes. +include::chapter-2-set-up.asciidoc[] -All you have to do is to define a mapper interface which declares any required mapping methods. During compilation, MapStruct will generate an implementation of this interface. This implementation uses plain Java method invocations for mapping between source and target objects, i.e. no reflection or similar. +include::chapter-3-defining-a-mapper.asciidoc[] -Compared to writing mapping code from hand, MapStruct saves time by generating code which is tedious and error-prone to write. Following a convention over configuration approach, MapStruct uses sensible defaults but steps out of your way when it comes to configuring or implementing special behavior. +include::chapter-4-retrieving-a-mapper.asciidoc[] -Compared to dynamic mapping frameworks, MapStruct offers the following advantages: +include::chapter-5-data-type-conversions.asciidoc[] -* Fast execution by using plain method invocations instead of reflection -* Compile-time type safety: Only objects and attributes mapping to each other can be mapped, no accidental mapping of an order entity into a customer DTO etc. -* Clear error-reports at build time, if - ** mappings are incomplete (not all target properties are mapped) - ** mappings are incorrect (cannot find a proper mapping method or type conversion) +include::chapter-6-mapping-collections.asciidoc[] -[[setup]] -== Set up +include::chapter-7-mapping-streams.asciidoc[] -MapStruct is a Java annotation processor based on http://www.jcp.org/en/jsr/detail?id=269[JSR 269] and as such can be used within command line builds (javac, Ant, Maven etc.) as well as from within your IDE. +include::chapter-8-mapping-values.asciidoc[] -It comprises the following artifacts: +include::chapter-9-object-factories.asciidoc[] -* _org.mapstruct:mapstruct_: contains the required annotations such as `@Mapping`; On Java 8 or later, use _org.mapstruct:mapstruct-jdk8_ instead which takes advantage of language improvements introduced in Java 8 -* _org.mapstruct:mapstruct-processor_: contains the annotation processor which generates mapper implementations +include::chapter-10-advanced-mapping-options.asciidoc[] -=== Apache Maven +include::chapter-11-reusing-mapping-configurations.asciidoc[] -For Maven based projects add the following to your POM file in order to use MapStruct: +include::chapter-12-customizing-mapping.asciidoc[] -.Maven configuration -==== -[source, xml, linenums] -[subs="verbatim,attributes"] ----- -... - - {mapstructVersion} - -... - - - org.mapstruct - mapstruct-jdk8 - ${org.mapstruct.version} - - -... - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.5.1 - - 1.8 - 1.8 - - - org.mapstruct - mapstruct-processor - ${org.mapstruct.version} - - - - - - -... ----- -==== +include::chapter-13-using-mapstruct-spi.asciidoc[] -[TIP] -==== -If you are working with the Eclipse IDE, make sure to have a current version of the http://www.eclipse.org/m2e/[M2E plug-in]. -When importing a Maven project configured as shown above, it will set up the MapStruct annotation processor so it runs right in the IDE, whenever you save a mapper type. -Neat, isn't it? - -To double check that everything is working as expected, go to your project's properties and select "Java Compiler" -> "Annotation Processing" -> "Factory Path". -The MapStruct processor JAR should be listed and enabled there. -Any processor options configured via the compiler plug-in (see below) should be listed under "Java Compiler" -> "Annotation Processing". - -If the processor is not kicking in, check that the configuration of annotation processors through M2E is enabled. -To do so, go to "Preferences" -> "Maven" -> "Annotation Processing" and select "Automatically configure JDT APT". -Alternatively, specify the following in the `properties` section of your POM file: `jdt_apt`. - -Also make sure that your project is using Java 1.6 or later (project properties -> "Java Compiler" -> "Compile Compliance Level"). -It will not work with older versions. -==== - -=== Gradle - -Add the following to your Gradle build file in order to enable MapStruct: - -.Gradle configuration -==== -[source, groovy, linenums] -[subs="verbatim,attributes"] ----- -... -plugins { - ... - id 'net.ltgt.apt' version '0.15' -} - -// You can integrate with your IDEs. -// See more details: https://github.com/tbroyer/gradle-apt-plugin#usage-with-ides -apply plugin: 'net.ltgt.apt-idea' -apply plugin: 'net.ltgt.apt-eclipse' - -dependencies { - ... - compile "org.mapstruct:mapstruct-jdk8:${mapstructVersion}" - - annotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" - // If you are using mapstruct in test code - testAnnotationProcessor "org.mapstruct:mapstruct-processor:${mapstructVersion}" -} -... ----- -==== - -You can find a complete example in the https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-on-gradle[mapstruct-examples] project on GitHub. - - -=== Apache Ant - -Add the `javac` task configured as follows to your _build.xml_ file in order to enable MapStruct in your Ant-based project. Adjust the paths as required for your project layout. - -.Ant configuration -==== -[source, xml, linenums] -[subs="verbatim,attributes"] ----- -... - - - - -... ----- -==== - -You can find a complete example in the https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-on-ant[mapstruct-examples] project on GitHub. - -[[configuration-options]] -=== Configuration options - -The MapStruct code generator can be configured using _annotation processor options_. - -When invoking javac directly, these options are passed to the compiler in the form _-Akey=value_. When using MapStruct via Maven, any processor options can be passed using an `options` element within the configuration of the Maven processor plug-in like this: - -.Maven configuration -==== -[source, xml, linenums] -[subs="verbatim,attributes"] ----- -... - - org.apache.maven.plugins - maven-compiler-plugin - 3.5.1 - - 1.8 - 1.8 - - - org.mapstruct - mapstruct-processor - ${org.mapstruct.version} - - - - - -Amapstruct.suppressGeneratorTimestamp=true - - - -Amapstruct.suppressGeneratorVersionInfoComment=true - - - - -... ----- -==== - -.Gradle configuration -==== -[source, groovy, linenums] -[subs="verbatim,attributes"] ----- -... -compileJava { - options.compilerArgs = [ - '-Amapstruct.suppressGeneratorTimestamp=true', - '-Amapstruct.suppressGeneratorVersionInfoComment=true' - ] -} -... ----- -==== - -The following options exist: - -.MapStruct processor options -[cols="1,2a,1"] -|=== -|Option|Purpose|Default - -|`mapstruct. -suppressGeneratorTimestamp` -|If set to `true`, the creation of a time stamp in the `@Generated` annotation in the generated mapper classes is suppressed. -|`false` - -|`mapstruct. -suppressGeneratorVersionInfoComment` -|If set to `true`, the creation of the `comment` attribute in the `@Generated` annotation in the generated mapper classes is suppressed. The comment contains information about the version of MapStruct and about the compiler used for the annotation processing. -|`false` - -|`mapstruct.defaultComponentModel` -|The name of the component model (see <>) based on which mappers should be generated. - -Supported values are: - -* `default`: the mapper uses no component model, instances are typically retrieved via `Mappers#getMapper(Class)` -* `cdi`: the generated mapper is an application-scoped CDI bean and can be retrieved via `@Inject` -* `spring`: the generated mapper is a singleton-scoped Spring bean and can be retrieved via `@Autowired` -* `jsr330`: the generated mapper is annotated with {@code @Named} and can be retrieved via `@Inject`, e.g. using Spring - -If a component model is given for a specific mapper via `@Mapper#componentModel()`, the value from the annotation takes precedence. -|`default` - -|`mapstruct.unmappedTargetPolicy` -|The default reporting policy to be applied in case an attribute of the target object of a mapping method is not populated with a source value. - -Supported values are: - -* `ERROR`: any unmapped target property will cause the mapping code generation to fail -* `WARN`: any unmapped target property will cause a warning at build time -* `IGNORE`: unmapped target properties are ignored - -If a policy is given for a specific mapper via `@Mapper#unmappedTargetPolicy()`, the value from the annotation takes precedence. -|`WARN` -|=== - -=== Using MapStruct on Java 9 - -MapStruct can be used with Java 9, but as that Java version has not been finalized yet, support for it is experimental. - -A core theme of Java 9 is the modularization of the JDK. One effect of this is that a specific module needs to be enabled for a project in order to use the `javax.annotation.Generated` annotation. `@Generated` is added by MapStruct to generated mapper classes to tag them as generated code, stating the date of generation, the generator version etc. - -To allow usage of the `@Generated` annotation the module _java.annotations.common_ must be enabled. When using Maven, this can be done like this: - - export MAVEN_OPTS="--add-modules java.annotations.common" - -If the `@Generated` annotation is not available, MapStruct will detect this situation and not add it to generated mappers. - -[[defining-mapper]] -== Defining a mapper - -In this section you'll learn how to define a bean mapper with MapStruct and which options you have to do so. - -[[basic-mappings]] -=== Basic mappings - -To create a mapper simply define a Java interface with the required mapping method(s) and annotate it with the `org.mapstruct.Mapper` annotation: - -.Java interface to define a mapper -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mappings({ - @Mapping(source = "make", target = "manufacturer"), - @Mapping(source = "numberOfSeats", target = "seatCount") - }) - CarDto carToCarDto(Car car); - - @Mapping(source = "name", target = "fullName") - PersonDto personToPersonDto(Person person); -} ----- -==== - -The `@Mapper` annotation causes the MapStruct code generator to create an implementation of the `CarMapper` interface during build-time. - -In the generated method implementations all readable properties from the source type (e.g. `Car`) will be copied into the corresponding property in the target type (e.g. `CarDto`): - -* When a property has the same name as its target entity counterpart, it will be mapped implicitly. -* When a property has a different name in the target entity, its name can be specified via the `@Mapping` annotation. - -[TIP] -==== -The property name as defined in the http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html[JavaBeans specification] must be specified in the `@Mapping` annotation, e.g. _seatCount_ for a property with the accessor methods `getSeatCount()` and `setSeatCount()`. -==== -[TIP] -==== -By means of the `@BeanMapping(ignoreByDefault = true)` the default behavior will be *explicit mapping*, meaning that all mappings have to be specified by means of the `@Mapping` and no warnings will be issued on missing target properties. -==== -[TIP] -==== -Fluent setters are also supported. -Fluent setters are setters that return the same type as the type being modified. - -E.g. - -``` -public Builder seatCount(int seatCount) { - this.seatCount = seatCount; - return this; -} -``` -==== - -[TIP] -==== -When using Java 8 or later, you can omit the `@Mappings` wrapper annotation and directly specify several `@Mapping` annotations on one method. -==== - -To get a better understanding of what MapStruct does have a look at the following implementation of the `carToCarDto()` method as generated by MapStruct: - -.Code generated by MapStruct -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -// GENERATED CODE -public class CarMapperImpl implements CarMapper { - - @Override - public CarDto carToCarDto(Car car) { - if ( car == null ) { - return null; - } - - CarDto carDto = new CarDto(); - - if ( car.getFeatures() != null ) { - carDto.setFeatures( new ArrayList( car.getFeatures() ) ); - } - carDto.setManufacturer( car.getMake() ); - carDto.setSeatCount( car.getNumberOfSeats() ); - carDto.setDriver( personToPersonDto( car.getDriver() ) ); - carDto.setPrice( String.valueOf( car.getPrice() ) ); - if ( car.getCategory() != null ) { - carDto.setCategory( car.getCategory().toString() ); - } - carDto.setEngine( engineToEngineDto( car.getEngine() ) ); - - return carDto; - } - - @Override - public PersonDto personToPersonDto(Person person) { - //... - } - - private EngineDto engineToEngineDto(Engine engine) { - if ( engine == null ) { - return null; - } - - EngineDto engineDto = new EngineDto(); - - engineDto.setHorsePower(engine.getHorsePower()); - engineDto.setFuel(engine.getFuel()); - - return engineDto; - } -} ----- -==== - -The general philosophy of MapStruct is to generate code which looks as much as possible as if you had written it yourself from hand. In particular this means that the values are copied from source to target by plain getter/setter invocations instead of reflection or similar. - -As the example shows the generated code takes into account any name mappings specified via `@Mapping`. -If the type of a mapped attribute is different in source and target entity, -MapStruct will either apply an automatic conversion (as e.g. for the _price_ property, see also <>) -or optionally invoke / create another mapping method (as e.g. for the _driver_ / _engine_ property, see also <>). -MapStruct will only create a new mapping method if and only if the source and target property are properties of a Bean and they themselves are Beans or simple properties. -i.e. they are not `Collection` or `Map` type properties. - -Collection-typed attributes with the same element type will be copied by creating a new instance of the target collection type containing the elements from the source property. For collection-typed attributes with different element types each element will be mapped individually and added to the target collection (see <>). - -MapStruct takes all public properties of the source and target types into account. This includes properties declared on super-types. - -[[adding-custom-methods]] -=== Adding custom methods to mappers - -In some cases it can be required to manually implement a specific mapping from one type to another which can't be generated by MapStruct. One way to handle this is to implement the custom method on another class which then is used by mappers generated by MapStruct (see <>). - -Alternatively, when using Java 8 or later, you can implement custom methods directly in a mapper interface as default methods. The generated code will invoke the default methods if the argument and return types match. - -As an example let's assume the mapping from `Person` to `PersonDto` requires some special logic which can't be generated by MapStruct. You could then define the mapper from the previous example like this: - -.Mapper which defines a custom mapping with a default method -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mappings({...}) - CarDto carToCarDto(Car car); - - default PersonDto personToPersonDto(Person person) { - //hand-written mapping logic - } -} ----- -==== - -The class generated by MapStruct implements the method `carToCarDto()`. The generated code in `carToCarDto()` will invoke the manually implemented `personToPersonDto()` method when mapping the `driver` attribute. - -A mapper could also be defined in the form of an abstract class instead of an interface and implement the custom methods directly in the mapper class. In this case MapStruct will generate an extension of the abstract class with implementations of all abstract methods. An advantage of this approach over declaring default methods is that additional fields could be declared in the mapper class. - -The previous example where the mapping from `Person` to `PersonDto` requires some special logic could then be defined like this: - -.Mapper defined by an abstract class -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public abstract class CarMapper { - - @Mappings(...) - public abstract CarDto carToCarDto(Car car); - - public PersonDto personToPersonDto(Person person) { - //hand-written mapping logic - } -} ----- -==== - -MapStruct will generate a sub-class of `CarMapper` with an implementation of the `carToCarDto()` method as it is declared abstract. The generated code in `carToCarDto()` will invoke the manually implemented `personToPersonDto()` method when mapping the `driver` attribute. - -[[mappings-with-several-source-parameters]] -=== Mapping methods with several source parameters - -MapStruct also supports mapping methods with several source parameters. This is useful e.g. in order to combine several entities into one data transfer object. The following shows an example: - -.Mapping method with several source parameters -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface AddressMapper { - - @Mappings({ - @Mapping(source = "person.description", target = "description"), - @Mapping(source = "address.houseNo", target = "houseNumber") - }) - DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Address address); -} ----- -==== - -The shown mapping method takes two source parameters and returns a combined target object. As with single-parameter mapping methods properties are mapped by name. - -In case several source objects define a property with the same name, the source parameter from which to retrieve the property must be specified using the `@Mapping` annotation as shown for the `description` property in the example. An error will be raised when such an ambiguity is not resolved. For properties which only exist once in the given source objects it is optional to specify the source parameter's name as it can be determined automatically. - -[WARNING] -==== -Specifying the parameter in which the property resides is mandatory when using the `@Mapping` annotation. -==== - -[TIP] -==== -Mapping methods with several source parameters will return `null` in case all the source parameters are `null`. Otherwise the target object will be instantiated and all properties from the provided parameters will be propagated. -==== - -MapStruct also offers the possibility to directly refer to a source parameter. - -.Mapping method directly referring to a source parameter -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface AddressMapper { - - @Mappings({ - @Mapping(source = "person.description", target = "description"), - @Mapping(source = "hn", target = "houseNumber") - }) - DeliveryAddressDto personAndAddressToDeliveryAddressDto(Person person, Integer hn); -} ----- -==== - -In this case the source parameter is directly mapped into the target as the example above demonstrates. The parameter `hn`, a non bean type (in this case `java.lang.Integer`) is mapped to `houseNumber`. - -[[updating-bean-instances]] -=== Updating existing bean instances - -In some cases you need mappings which don't create a new instance of the target type but instead update an existing instance of that type. This sort of mapping can be realized by adding a parameter for the target object and marking this parameter with `@MappingTarget`. The following shows an example: - -.Update method -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - void updateCarFromDto(CarDto carDto, @MappingTarget Car car); -} ----- -==== - -The generated code of the `updateCarFromDto()` method will update the passed `Car` instance with the properties from the given `CarDto` object. There may be only one parameter marked as mapping target. Instead of `void` you may also set the method's return type to the type of the target parameter, which will cause the generated implementation to update the passed mapping target and return it as well. This allows for fluent invocations of mapping methods. - -Collection- or map-typed properties of the target bean to be updated will be cleared and then populated with the values from the corresponding source collection or map. - -[[direct-field-mappings]] -=== Mappings with direct field access - -MapStruct also supports mappings of `public` fields that have no getters/setters. MapStruct will -use the fields as read/write accessor if it cannot find suitable getter/setter methods for the property. - -A field is considered as a read accessor if it is `public` or `public final`. If a field is `static` it is not -considered as a read accessor. - -A field is considered as a write accessor only if it is `public`. If a field is `final` and/or `static` it is not -considered as a write accessor. - -Small example: - -.Example classes for mapping -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class Customer { - - private Long id; - private String name; - - //getters and setter omitted for brevity -} - -public class CustomerDto { - - public Long id; - public String customerName; -} - -@Mapper -public interface CustomerMapper { - - CustomerMapper MAPPER = Mappers.getMapper( CustomerMapper.class ); - - @Mapping(source = "customerName", target = "name") - Customer toCustomer(CustomerDto customerDto); - - @InheritInverseConfiguration - CustomerDto fromCustomer(Customer customer); -} ----- -==== - -For the configuration from above, the generated mapper looks like: - -.Generated mapper for example classes -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -// GENERATED CODE -public class CustomerMapperImpl implements CustomerMapper { - - @Override - public Customer toCustomer(CustomerDto customerDto) { - // ... - customer.setId( customerDto.id ); - customer.setName( customerDto.customerName ); - // ... - } - - @Override - public CustomerDto fromCustomer(Customer customer) { - // ... - customerDto.id = customer.getId(); - customerDto.customerName = customer.getName(); - // ... - } -} ----- -==== - -You can find the complete example in the -https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-field-mapping[mapstruct-examples-field-mapping] -project on GitHub. - -[[mapping-with-builders]] -=== Using builders - -MapStruct also supports mapping of immutable types via builders. -When performing a mapping MapStruct checks if there is a builder for the type being mapped. -This is done via the `BuilderProvider` SPI. -If a Builder exists for a certain type, than that builder will be used for the mappings. - -The default implementation of the `BuilderProvider` assumes the following: - -* The type has a parameterless public static builder creation method that returns a builder. -So for example `Person` has a public static method that returns `PersonBuilder`. -* The builder type has a parameterless public method (build method) that returns the type being build -In our example `PersonBuilder` has a method returning `Person`. -* In case there are multiple build methods, MapStruct will look for a method called `build`, if such method exists -then this would be used, otherwise a compilation error would be created. -* A specific build method can be defined by using `@Builder` within: `@BeanMapping`, `@Mapper` or `@MapperConfig` -* In case there are multiple builder creation methods that satisfy the above conditions then a `MoreThanOneBuilderCreationMethodException` -will be thrown from the `DefaultBuilderProvider` SPI. -In case of a `MoreThanOneBuilderCreationMethodException` MapStruct will write a warning in the compilation and not use any builder. - -If such type is found then MapStruct will use that type to perform the mapping to (i.e. it will look for setters into that type). -To finish the mapping MapStruct generates code that will invoke the build method of the builder. - -[NOTE] -====== -The <> are also considered for the builder type. -E.g. If an object factory exists for our `PersonBuilder` than this factory would be used instead of the builder creation method. -====== - -.Person with Builder example -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class Person { - - private final String name; - - protected Person(Person.Builder builder) { - this.name = builder.name; - } - - public static Person.Builder builder() { - return new Person.Builder(); - } - - public static class Builder { - - private String name; - - public Builder name(String name) { - this.name = name; - return this; - } - - public Person create() { - return new Person( this ); - } - } -} ----- -==== - -.Person Mapper definition -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public interface PersonMapper { - - Person map(PersonDto dto); -} ----- -==== - -.Generated mapper with builder -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -// GENERATED CODE -public class PersonMapperImpl implements PersonMapper { - - public Person map(PersonDto dto) { - if (dto == null) { - return null; - } - - Person.Builder builder = Person.builder(); - - builder.name( dto.getName() ); - - return builder.create(); - } -} ----- -==== - -Supported builder frameworks: - -* https://projectlombok.org/[Lombok] - requires having the Lombok classes in a separate module. See for more information https://github.com/rzwitserloot/lombok/issues/1538[rzwitserloot/lombok#1538] -* https://github.com/google/auto/blob/master/value/userguide/index.md[AutoValue] -* https://immutables.github.io/[Immutables] - When Immutables are present on the annotation processor path then the `ImmutablesAccessorNamingStrategy` and `ImmutablesBuilderProvider` would be used by default -* https://github.com/google/FreeBuilder[FreeBuilder] -* It also works for custom builders (handwritten ones) if the implementation supports the defined rules for the default `BuilderProvider`. -Otherwise, you would need to write a custom `BuilderProvider` - -[TIP] -==== -In case you want to disable using builders then you can use the `NoOpBuilderProvider` by creating a `org.mapstruct.ap.spi.BuilderProvider` file in the `META-INF/services` directory with `org.mapstruct.ap.spi.NoOpBuilderProvider` as it's content. -==== - -[[retrieving-mapper]] -== Retrieving a mapper - -[[mappers-factory]] -=== The Mappers factory - -Mapper instances can be retrieved via the `org.mapstruct.factory.Mappers` class. Just invoke the `getMapper()` method, passing the interface type of the mapper to return: - -.Using the Mappers factory -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -CarMapper mapper = Mappers.getMapper( CarMapper.class ); ----- -==== - -By convention, a mapper interface should define a member called `INSTANCE` which holds a single instance of the mapper type: - -.Declaring an instance of a mapper -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); - - CarDto carToCarDto(Car car); -} - ----- -==== - -This pattern makes it very easy for clients to use mapper objects without repeatedly instantiating new instances: - -.Accessing a mapper -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -Car car = ...; -CarDto dto = CarMapper.INSTANCE.carToCarDto( car ); ----- -==== - -Note that mappers generated by MapStruct are thread-safe and thus can safely be accessed from several threads at the same time. - -[[using-dependency-injection]] -=== Using dependency injection - -If you're working with a dependency injection framework such as http://jcp.org/en/jsr/detail?id=346[CDI] (Contexts and Dependency Injection for Java^TM^ EE) or the http://www.springsource.org/spring-framework[Spring Framework], it is recommended to obtain mapper objects via dependency injection as well. For that purpose you can specify the component model which generated mapper classes should be based on either via `@Mapper#componentModel` or using a processor option as described in <>. - -Currently there is support for CDI and Spring (the latter either via its custom annotations or using the JSR 330 annotations). See <> for the allowed values of the `componentModel` attribute which are the same as for the `mapstruct.defaultComponentModel` processor option. In both cases the required annotations will be added to the generated mapper implementations classes in order to make the same subject to dependency injection. The following shows an example using CDI: - -.A mapper using the CDI component model -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(componentModel = "cdi") -public interface CarMapper { - - CarDto carToCarDto(Car car); -} - ----- -==== - -The generated mapper implementation will be marked with the `@ApplicationScoped` annotation and thus can be injected into fields, constructor arguments etc. using the `@Inject` annotation: - -.Obtaining a mapper via dependency injection -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Inject -private CarMapper mapper; ----- -==== - -A mapper which uses other mapper classes (see <>) will obtain these mappers using the configured component model. So if `CarMapper` from the previous example was using another mapper, this other mapper would have to be an injectable CDI bean as well. - -[[injection-strategy]] -=== Injection strategy - -When using <>, you can choose between field and constructor injection. -This can be done by either providing the injection strategy via `@Mapper` or `@MapperConfig` annotation. - -.Using constructor injection -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(componentModel = "cdi", uses = EngineMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR) -public interface CarMapper { - CarDto carToCarDto(Car car); -} ----- -==== - -The generated mapper will inject all classes defined in the **uses** attribute. -When `InjectionStrategy#CONSTRUCTOR` is used, the constructor will have the appropriate annotation and the fields won't. -When `InjectionStrategy#FIELD` is used, the annotation is on the field itself. -For now, the default injection strategy is field injection. -It is recommended to use constructor injection to simplify testing. - -[TIP] -==== -For abstract classes or decorators setter injection should be used. -==== - -[[datatype-conversions]] -== Data type conversions - -Not always a mapped attribute has the same type in the source and target objects. For instance an attribute may be of type `int` in the source bean but of type `Long` in the target bean. - -Another example are references to other objects which should be mapped to the corresponding types in the target model. E.g. the class `Car` might have a property `driver` of the type `Person` which needs to be converted into a `PersonDto` object when mapping a `Car` object. - -In this section you'll learn how MapStruct deals with such data type conversions. - -[[implicit-type-conversions]] -=== Implicit type conversions - -MapStruct takes care of type conversions automatically in many cases. If for instance an attribute is of type `int` in the source bean but of type `String` in the target bean, the generated code will transparently perform a conversion by calling `String#valueOf(int)` and `Integer#parseInt(String)`, respectively. - -Currently the following conversions are applied automatically: - -* Between all Java primitive data types and their corresponding wrapper types, e.g. between `int` and `Integer`, `boolean` and `Boolean` etc. The generated code is `null` aware, i.e. when converting a wrapper type into the corresponding primitive type a `null` check will be performed. - -* Between all Java primitive number types and the wrapper types, e.g. between `int` and `long` or `byte` and `Integer`. - -[WARNING] -==== -Converting from larger data types to smaller ones (e.g. from `long` to `int`) can cause a value or precision loss. There https://github.com/mapstruct/mapstruct/issues/5[will be] an option for raising a warning in such cases in a future MapStruct version. -==== - -* Between all Java primitive types (including their wrappers) and `String`, e.g. between `int` and `String` or `Boolean` and `String`. A format string as understood by `java.text.DecimalFormat` can be specified. - -.Conversion from int to String -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mapping(source = "price", numberFormat = "$#.00") - CarDto carToCarDto(Car car); - - @IterableMapping(numberFormat = "$#.00") - List prices(List prices); -} ----- -==== -* Between `enum` types and `String`. - -* Between big number types (`java.math.BigInteger`, `java.math.BigDecimal`) and Java primitive types (including their wrappers) as well as String. A format string as understood by `java.text.DecimalFormat` can be specified. - -.Conversion from BigDecimal to String -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mapping(source = "power", numberFormat = "#.##E0") - CarDto carToCarDto(Car car); - -} ----- -==== - - -* Between `JAXBElement` and `T`, `List>` and `List` - -* Between `java.util.Calendar`/`java.util.Date` and JAXB's `XMLGregorianCalendar` - -* Between `java.util.Date`/`XMLGregorianCalendar` and `String`. A format string as understood by `java.text.SimpleDateFormat` can be specified via the `dateFormat` option as this: - -.Conversion from Date to String -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mapping(source = "manufacturingDate", dateFormat = "dd.MM.yyyy") - CarDto carToCarDto(Car car); - - @IterableMapping(dateFormat = "dd.MM.yyyy") - List stringListToDateList(List dates); -} ----- -==== - -* Between Jodas `org.joda.time.DateTime`, `org.joda.time.LocalDateTime`, `org.joda.time.LocalDate`, `org.joda.time.LocalTime` and `String`. A format string as understood by `java.text.SimpleDateFormat` can be specified via the `dateFormat` option (see above). - -* Between Jodas `org.joda.time.DateTime` and `javax.xml.datatype.XMLGregorianCalendar`, `java.util.Calendar`. - -* Between Jodas `org.joda.time.LocalDateTime`, `org.joda.time.LocalDate` and `javax.xml.datatype.XMLGregorianCalendar`, `java.util.Date`. - -* Between `java.time.ZonedDateTime`, `java.time.LocalDateTime`, `java.time.LocalDate`, `java.time.LocalTime` from Java 8 Date-Time package and `String`. A format string as understood by `java.text.SimpleDateFormat` can be specified via the `dateFormat` option (see above). - -* Between `java.time.ZonedDateTime` from Java 8 Date-Time package and `java.util.Date` where, when mapping a `ZonedDateTime` from a given `Date`, the system default timezone is used. - -* Between `java.time.LocalDateTime` from Java 8 Date-Time package and `java.util.Date` where timezone UTC is used as the timezone. - -* Between `java.time.LocalDate` from Java 8 Date-Time package and `java.util.Date` where timezone UTC is used as the timezone. - -* Between `java.time.ZonedDateTime` from Java 8 Date-Time package and `java.util.Calendar`. - -* Between `java.sql.Date` and `java.util.Date` - -* Between `java.sql.Time` and `java.util.Date` - -* Between `java.sql.Timestamp` and `java.util.Date` - -* When converting from a `String`, omitting `Mapping#dateFormat`, it leads to usage of the default pattern and date format symbols for the default locale. An exception to this rule is `XmlGregorianCalendar` which results in parsing the `String` according to http://www.w3.org/TR/xmlschema-2/#dateTime[XML Schema 1.0 Part 2, Section 3.2.7-14.1, Lexical Representation]. - -* Between `java.util.Currency` and `String`. -** When converting from a `String`, the value needs to be a valid https://en.wikipedia.org/wiki/ISO_4217[ISO-4217] alphabetic code otherwise an `IllegalArgumentException` is thrown - -[[mapping-object-references]] -=== Mapping object references - -Typically an object has not only primitive attributes but also references other objects. E.g. the `Car` class could contain a reference to a `Person` object (representing the car's driver) which should be mapped to a `PersonDto` object referenced by the `CarDto` class. - -In this case just define a mapping method for the referenced object type as well: - -.Mapper with one mapping method using another -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - CarDto carToCarDto(Car car); - - PersonDto personToPersonDto(Person person); -} ----- -==== - -The generated code for the `carToCarDto()` method will invoke the `personToPersonDto()` method for mapping the `driver` attribute, while the generated implementation for `personToPersonDto()` performs the mapping of person objects. - -That way it is possible to map arbitrary deep object graphs. When mapping from entities into data transfer objects it is often useful to cut references to other entities at a certain point. To do so, implement a custom mapping method (see the next section) which e.g. maps a referenced entity to its id in the target object. - -When generating the implementation of a mapping method, MapStruct will apply the following routine for each attribute pair in the source and target object: - -* If source and target attribute have the same type, the value will be simply copied from source to target. If the attribute is a collection (e.g. a `List`) a copy of the collection will be set into the target attribute. -* If source and target attribute type differ, check whether there is another mapping method which has the type of the source attribute as parameter type and the type of the target attribute as return type. If such a method exists it will be invoked in the generated mapping implementation. -* If no such method exists MapStruct will look whether a built-in conversion for the source and target type of the attribute exists. If this is the case, the generated mapping code will apply this conversion. -* If no such method was found MapStruct will try to generate an automatic sub-mapping method that will do the mapping between the source and target attributes. -* If MapStruct could not create a name based mapping method an error will be raised at build time, indicating the non-mappable attribute and its path. - -[NOTE] -==== -In order to stop MapStruct from generating automatic sub-mapping methods, one can use `@Mapper( disableSubMappingMethodsGeneration = true )`. -==== - -[NOTE] -==== -During the generation of automatic sub-mapping methods <> will not be taken into consideration, yet. -Follow issue https://github.com/mapstruct/mapstruct/issues/1086[#1086] for more information. -==== - -include::controlling-nested-bean-mappings.asciidoc[] - -[[invoking-other-mappers]] -=== Invoking other mappers - -In addition to methods defined on the same mapper type MapStruct can also invoke mapping methods defined in other classes, be it mappers generated by MapStruct or hand-written mapping methods. This can be useful to structure your mapping code in several classes (e.g. with one mapper type per application module) or if you want to provide custom mapping logic which can't be generated by MapStruct. - -For instance the `Car` class might contain an attribute `manufacturingDate` while the corresponding DTO attribute is of type String. In order to map this attribute, you could implement a mapper class like this: - -.Manually implemented mapper class -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class DateMapper { - - public String asString(Date date) { - return date != null ? new SimpleDateFormat( "yyyy-MM-dd" ) - .format( date ) : null; - } - - public Date asDate(String date) { - try { - return date != null ? new SimpleDateFormat( "yyyy-MM-dd" ) - .parse( date ) : null; - } - catch ( ParseException e ) { - throw new RuntimeException( e ); - } - } -} ----- -==== - -In the `@Mapper` annotation at the `CarMapper` interface reference the `DateMapper` class like this: - -.Referencing another mapper class -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(uses=DateMapper.class) -public class CarMapper { - - CarDto carToCarDto(Car car); -} ----- -==== - -When generating code for the implementation of the `carToCarDto()` method, MapStruct will look for a method which maps a `Date` object into a String, find it on the `DateMapper` class and generate an invocation of `asString()` for mapping the `manufacturingDate` attribute. - -Generated mappers retrieve referenced mappers using the component model configured for them. If e.g. CDI was used as component model for `CarMapper`, `DateMapper` would have to be a CDI bean as well. When using the default component model, any hand-written mapper classes to be referenced by MapStruct generated mappers must declare a public no-args constructor in order to be instantiable. - -[[passing-target-type]] -=== Passing the mapping target type to custom mappers - -When having a custom mapper hooked into the generated mapper with `@Mapper#uses()`, an additional parameter of type `Class` (or a super-type of it) can be defined in the custom mapping method in order to perform general mapping tasks for specific target object types. That attribute must be annotated with `@TargetType` for MapStruct to generate calls that pass the `Class` instance representing the corresponding property type of the target bean. - -For instance, the `CarDto` could have a property `owner` of type `Reference` that contains the primary key of a `Person` entity. You could now create a generic custom mapper that resolves any `Reference` objects to their corresponding managed JPA entity instances. - -.Mapping method expecting mapping target type as parameter -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@ApplicationScoped // CDI component model -public class ReferenceMapper { - - @PersistenceContext - private EntityManager entityManager; - - public T resolve(Reference reference, @TargetType Class entityClass) { - return reference != null ? entityManager.find( entityClass, reference.getPk() ) : null; - } - - public Reference toReference(BaseEntity entity) { - return entity != null ? new Reference( entity.getPk() ) : null; - } -} - -@Mapper(componentModel = "cdi", uses = ReferenceMapper.class ) -public interface CarMapper { - - Car carDtoToCar(CarDto carDto); -} ----- -==== - -MapStruct will then generate something like this: - -.Generated code -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -@ApplicationScoped -public class CarMapperImpl implements CarMapper { - - @Inject - private ReferenceMapper referenceMapper; - - @Override - public Car carDtoToCar(CarDto carDto) { - if ( carDto == null ) { - return null; - } - - Car car = new Car(); - - car.setOwner( referenceMapper.resolve( carDto.getOwner(), Owner.class ) ); - // ... - - return car; - } -} ----- -==== - -[[passing-context]] -=== Passing context or state objects to custom methods - -Additional _context_ or _state_ information can be passed through generated mapping methods to custom methods with `@Context` parameters. Such parameters are passed to other mapping methods, `@ObjectFactory` methods (see <>) or `@BeforeMapping` / `@AfterMapping` methods (see <>) when applicable and can thus be used in custom code. - -`@Context` parameters are searched for `@ObjectFactory` methods, which are called on the provided context parameter value if applicable. - -`@Context` parameters are also searched for `@BeforeMapping` / `@AfterMapping` methods, which are called on the provided context parameter value if applicable. - -*Note:* no `null` checks are performed before calling before/after mapping methods on context parameters. The caller needs to make sure that `null` is not passed in that case. - -For generated code to call a method that is declared with `@Context` parameters, the declaration of the mapping method being generated needs to contain at least those (or assignable) `@Context` parameters as well. The generated code will not create new instances of missing `@Context` parameters nor will it pass a literal `null` instead. - -.Using `@Context` parameters for passing data down to hand-written property mapping methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public abstract CarDto toCar(Car car, @Context Locale translationLocale); - -protected OwnerManualDto translateOwnerManual(OwnerManual ownerManual, @Context Locale locale) { - // manually implemented logic to translate the OwnerManual with the given Locale -} ----- -==== - -MapStruct will then generate something like this: - -.Generated code -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -public CarDto toCar(Car car, Locale translationLocale) { - if ( car == null ) { - return null; - } - - CarDto carDto = new CarDto(); - - carDto.setOwnerManual( translateOwnerManual( car.getOwnerManual(), translationLocale ); - // more generated mapping code - - return carDto; -} ----- -==== - - -[[mapping-method-resolution]] -=== Mapping method resolution - -When mapping a property from one type to another, MapStruct looks for the most specific method which maps the source type into the target type. The method may either be declared on the same mapper interface or on another mapper which is registered via `@Mapper#uses()`. The same applies for factory methods (see <>). - -The algorithm for finding a mapping or factory method resembles Java's method resolution algorithm as much as possible. In particular, methods with a more specific source type will take precedence (e.g. if there are two methods, one which maps the searched source type, and another one which maps a super-type of the same). In case more than one most-specific method is found, an error will be raised. - -[TIP] -==== -When working with JAXB, e.g. when converting a `String` to a corresponding `JAXBElement`, MapStruct will take the `scope` and `name` attributes of `@XmlElementDecl` annotations into account when looking for a mapping method. This makes sure that the created `JAXBElement` instances will have the right QNAME value. You can find a test which maps JAXB objects https://github.com/mapstruct/mapstruct/blob/{mapstructVersion}/integrationtest/src/test/resources/jaxbTest/src/test/java/org/mapstruct/itest/jaxb/JaxbBasedMapperTest.java[here]. -==== - -[[selection-based-on-qualifiers]] -=== Mapping method selection based on qualifiers - -In many occasions one requires mapping methods with the same method signature (apart from the name) that have different behavior. -MapStruct has a handy mechanism to deal with such situations: `@Qualifier` (`org.mapstruct.Qualifier`). -A ‘qualifier’ is a custom annotation that the user can write, ‘stick onto’ a mapping method which is included as used mapper -and can be referred to in a bean property mapping, iterable mapping or map mapping. -Multiple qualifiers can be ‘stuck onto’ a method and mapping. - -So, let's say there is a hand-written method to map titles with a `String` return type and `String` argument amongst many other referenced mappers with the same `String` return type - `String` argument signature: - -.Several mapping methods with identical source and target types -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class Titles { - - public String translateTitleEG(String title) { - // some mapping logic - } - - public String translateTitleGE(String title) { - // some mapping logic - } -} ----- -==== - -And a mapper using this handwritten mapper, in which source and target have a property 'title' that should be mapped: - -.Mapper causing an ambiguous mapping method error -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper( uses = Titles.class ) -public interface MovieMapper { - - GermanRelease toGerman( OriginalRelease movies ); - -} ----- -==== - -Without the use of qualifiers, this would result in an ambiguous mapping method error, because 2 qualifying methods are found (`translateTitleEG`, `translateTitleGE`) and MapStruct would not have a hint which one to choose. - -Enter the qualifier approach: - -.Declaring a qualifier type -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -import org.mapstruct.Qualifier; - -@Qualifier -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.CLASS) -public @interface TitleTranslator { -} ----- -==== - -And, some qualifiers to indicate which translator to use to map from source language to target language: - -.Declaring qualifier types for mapping methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -import org.mapstruct.Qualifier; - -@Qualifier -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface EnglishToGerman { -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -import org.mapstruct.Qualifier; - -@Qualifier -@Target(ElementType.METHOD) -@Retention(RetentionPolicy.CLASS) -public @interface GermanToEnglish { -} ----- -==== - -Please take note of the retention `TitleTranslator` on class level, `EnglishToGerman`, `GermanToEnglish` on method level! - -Then, using the qualifiers, the mapping could look like this: - -.Mapper using qualifiers -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper( uses = Titles.class ) -public interface MovieMapper { - - @Mapping( target = "title", qualifiedBy = { TitleTranslator.class, EnglishToGerman.class } ) - GermanRelease toGerman( OriginalRelease movies ); - -} ----- -==== - -.Custom mapper qualifying the methods it provides -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@TitleTranslator -public class Titles { - - @EnglishToGerman - public String translateTitleEG(String title) { - // some mapping logic - } - - @GermanToEnglish - public String translateTitleGE(String title) { - // some mapping logic - } -} ----- -==== - -[WARNING] -==== -Please make sure the used retention policy equals retention policy `CLASS` (`@Retention(RetentionPolicy.CLASS)`). -==== - -[WARNING] -==== -A class / method annotated with a qualifier will not qualify anymore for mappings that do not have the `qualifiedBy` element. -==== - -[TIP] -==== -The same mechanism is also present on bean mappings: `@BeanMapping#qualifiedBy`: it selects the factory method marked with the indicated qualifier. -==== - -In many occasions, declaring a new annotation to aid the selection process can be too much for what you try to achieve. For those situations, MapStruct has the `@Named` annotation. This annotation is a pre-defined qualifier (annotated with `@Qualifier` itself) and can be used to name a Mapper or, more directly a mapping method by means of its value. The same example above would look like: - -.Custom mapper, annotating the methods to qualify by means of `@Named` -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Named("TitleTranslator") -public class Titles { - - @Named("EnglishToGerman") - public String translateTitleEG(String title) { - // some mapping logic - } - - @Named("GermanToEnglish") - public String translateTitleGE(String title) { - // some mapping logic - } -} ----- -==== - -.Mapper using named -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper( uses = Titles.class ) -public interface MovieMapper { - - @Mapping( target = "title", qualifiedByName = { "TitleTranslator", "EnglishToGerman" } ) - GermanRelease toGerman( OriginalRelease movies ); - -} ----- -==== - -[WARNING] -==== -Although the used mechanism is the same, the user has to be a bit more careful. Refactoring the name of a defined qualifier in an IDE will neatly refactor all other occurrences as well. This is obviously not the case for changing a name. -==== - - -[[mapping-collections]] -== Mapping collections - -The mapping of collection types (`List`, `Set` etc.) is done in the same way as mapping bean types, i.e. by defining mapping methods with the required source and target types in a mapper interface. MapStruct supports a wide range of iterable types from the http://docs.oracle.com/javase/tutorial/collections/intro/index.html[Java Collection Framework]. - -The generated code will contain a loop which iterates over the source collection, converts each element and puts it into the target collection. If a mapping method for the collection element types is found in the given mapper or the mapper it uses, this method is invoked to perform the element conversion. Alternatively, if an implicit conversion for the source and target element types exists, this conversion routine will be invoked. The following shows an example: - -.Mapper with collection mapping methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - Set integerSetToStringSet(Set integers); - - List carsToCarDtos(List cars); - - CarDto carToCarDto(Car car); -} ----- -==== - -The generated implementation of the `integerSetToStringSet` performs the conversion from `Integer` to `String` for each element, while the generated `carsToCarDtos()` method invokes the `carToCarDto()` method for each contained element as shown in the following: - -.Generated collection mapping methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -@Override -public Set integerSetToStringSet(Set integers) { - if ( integers == null ) { - return null; - } - - Set set = new HashSet(); - - for ( Integer integer : integers ) { - set.add( String.valueOf( integer ) ); - } - - return set; -} - -@Override -public List carsToCarDtos(List cars) { - if ( cars == null ) { - return null; - } - - List list = new ArrayList(); - - for ( Car car : cars ) { - list.add( carToCarDto( car ) ); - } - - return list; -} ----- -==== - -Note that MapStruct will look for a collection mapping method with matching parameter and return type, when mapping a collection-typed attribute of a bean, e.g. from `Car#passengers` (of type `List`) to `CarDto#passengers` (of type `List`). - -.Usage of collection mapping method to map a bean property -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -carDto.setPassengers( personsToPersonDtos( car.getPassengers() ) ); -... ----- -==== - -Some frameworks and libraries only expose JavaBeans getters but no setters for collection-typed properties. Types generated from an XML schema using JAXB adhere to this pattern by default. In this case the generated code for mapping such a property invokes its getter and adds all the mapped elements: - -.Usage of an adding method for collection mapping -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -carDto.getPassengers().addAll( personsToPersonDtos( car.getPassengers() ) ); -... ----- -==== - -[WARNING] -==== -It is not allowed to declare mapping methods with an iterable source and a non-iterable target or the other way around. An error will be raised when detecting this situation. -==== - -[[mapping-maps]] -=== Mapping maps - -Also map-based mapping methods are supported. The following shows an example: - -.Map mapping method -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public interface SourceTargetMapper { - - @MapMapping(valueDateFormat = "dd.MM.yyyy") - Map longDateMapToStringStringMap(Map source); -} ----- -==== - -Similar to iterable mappings, the generated code will iterate through the source map, convert each value and key (either by means of an implicit conversion or by invoking another mapping method) and put them into the target map: - -.Generated implementation of map mapping method -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -@Override -public Map stringStringMapToLongDateMap(Map source) { - if ( source == null ) { - return null; - } - - Map map = new HashMap(); - - for ( Map.Entry entry : source.entrySet() ) { - - Long key = Long.parseLong( entry.getKey() ); - Date value; - try { - value = new SimpleDateFormat( "dd.MM.yyyy" ).parse( entry.getValue() ); - } - catch( ParseException e ) { - throw new RuntimeException( e ); - } - - map.put( key, value ); - } - - return map; -} ----- -==== - -[[collection-mapping-strategies]] -=== Collection mapping strategies - -MapStruct has a `CollectionMappingStrategy`, with the possible values: `ACCESSOR_ONLY`, `SETTER_PREFERRED`, `ADDER_PREFERRED` and `TARGET_IMMUTABLE`. - -In the table below, the dash `-` indicates a property name. Next, the trailing `s` indicates the plural form. The table explains the options and how they are applied to the presence/absense of a `set-s`, `add-` and / or `get-s` method on the target object: - -.Collection mapping strategy options -|=== -|Option|Only target set-s Available|Only target add- Available|Both set-s / add- Available|No set-s / add- Available|Existing Target(`@TargetType`) - -|`ACCESSOR_ONLY` -|set-s -|get-s -|set-s -|get-s -|get-s - -|`SETTER_PREFERRED` -|set-s -|add- -|set-s -|get-s -|get-s - -|`ADDER_PREFERRED` -|set-s -|add- -|add- -|get-s -|get-s - -|`TARGET_IMMUTABLE` -|set-s -|exception -|set-s -|exception -|set-s -|=== - -Some background: An `adder` method is typically used in case of http://www.eclipse.org/webtools/dali/[generated (JPA) entities], to add a single element (entity) to an underlying collection. Invoking the adder establishes a parent-child relation between parent - the bean (entity) on which the adder is invoked - and its child(ren), the elements (entities) in the collection. To find the appropriate `adder`, MapStruct will try to make a match between the generic parameter type of the underlying collection and the single argument of a candidate `adder`. When there are more candidates, the plural `setter` / `getter` name is converted to singular and will be used in addition to make a match. - -The option `DEFAULT` should not be used explicitly. It is used to distinguish between an explicit user desire to override the default in a `@MapperConfig` from the implicit Mapstruct choice in a `@Mapper`. The option `DEFAULT` is synonymous to `ACCESSOR_ONLY`. - -[TIP] -==== -When working with an `adder` method and JPA entities, Mapstruct assumes that the target collections are initialized with a collection implementation (e.g. an `ArrayList`). You can use factories to create a new target entity with intialized collections instead of Mapstruct creating the target entity by its constructor. -==== - -[[implementation-types-for-collection-mappings]] -=== Implementation types used for collection mappings - -When an iterable or map mapping method declares an interface type as return type, one of its implementation types will be instantiated in the generated code. The following table shows the supported interface types and their corresponding implementation types as instantiated in the generated code: - -.Collection mapping implementation types -|=== -|Interface type|Implementation type - -|`Iterable`|`ArrayList` - -|`Collection`|`ArrayList` - -|`List`|`ArrayList` - -|`Set`|`HashSet` - -|`SortedSet`|`TreeSet` - -|`NavigableSet`|`TreeSet` - -|`Map`|`HashMap` - -|`SortedMap`|`TreeMap` - -|`NavigableMap`|`TreeMap` - -|`ConcurrentMap`|`ConcurrentHashMap` -|`ConcurrentNavigableMap`|`ConcurrentSkipListMap` -|=== - -include::mapping-streams.asciidoc[] - -[[mapping-enum-types]] -== Mapping Values - -=== Mapping enum types - -MapStruct supports the generation of methods which map one Java enum type into another. - -By default, each constant from the source enum is mapped to a constant with the same name in the target enum type. If required, a constant from the source enum may be mapped to a constant with another name with help of the `@ValueMapping` annotation. Several constants from the source enum can be mapped to the same constant in the target type. - -The following shows an example: - -.Enum mapping method -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface OrderMapper { - - OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class ); - - @ValueMappings({ - @ValueMapping(source = "EXTRA", target = "SPECIAL"), - @ValueMapping(source = "STANDARD", target = "DEFAULT"), - @ValueMapping(source = "NORMAL", target = "DEFAULT") - }) - ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); -} ----- -==== - -.Enum mapping method result -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -// GENERATED CODE -public class OrderMapperImpl implements OrderMapper { - - @Override - public ExternalOrderType orderTypeToExternalOrderType(OrderType orderType) { - if ( orderType == null ) { - return null; - } - - ExternalOrderType externalOrderType_; - - switch ( orderType ) { - case EXTRA: externalOrderType_ = ExternalOrderType.SPECIAL; - break; - case STANDARD: externalOrderType_ = ExternalOrderType.DEFAULT; - break; - case NORMAL: externalOrderType_ = ExternalOrderType.DEFAULT; - break; - case RETAIL: externalOrderType_ = ExternalOrderType.RETAIL; - break; - case B2B: externalOrderType_ = ExternalOrderType.B2B; - break; - default: throw new IllegalArgumentException( "Unexpected enum constant: " + orderType ); - } - - return externalOrderType_; - } -} ----- -==== -By default an error will be raised by MapStruct in case a constant of the source enum type does not have a corresponding constant with the same name in the target type and also is not mapped to another constant via `@ValueMapping`. This ensures that all constants are mapped in a safe and predictable manner. The generated -mapping method will throw an IllegalStateException if for some reason an unrecognized source value occurs. - -MapStruct also has a mechanism for mapping any remaining (unspecified) mappings to a default. This can be used only once in a set of value mappings. It comes in two flavors: `` and ``. - -In case of source `` MapStruct will continue to map a source enum constant to a target enum constant with the same name. The remainder of the source enum constants will be mapped to the target specified in the `@ValueMapping` with `` source. - -MapStruct will *not* attempt such name based mapping for `` and directly apply the target specified in the `@ValueMapping` with `` source to the remainder. - -MapStruct is able to handle `null` sources and `null` targets by means of the `` keyword. - -[TIP] -==== -Constants for ``, `` and `` are available in the `MappingConstants` class. -==== - -Finally `@InheritInverseConfiguration` and `@InheritConfiguration` can be used in combination with `@ValueMappings`. - -.Enum mapping method, and -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface SpecialOrderMapper { - - SpecialOrderMapper INSTANCE = Mappers.getMapper( SpecialOrderMapper.class ); - - @ValueMappings({ - @ValueMapping( source = MappingConstants.NULL, target = "DEFAULT" ), - @ValueMapping( source = "STANDARD", target = MappingConstants.NULL ), - @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "SPECIAL" ) - }) - ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); -} ----- -==== - -.Enum mapping method result, and -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -// GENERATED CODE -public class SpecialOrderMapperImpl implements SpecialOrderMapper { - - @Override - public ExternalOrderType orderTypeToExternalOrderType(OrderType orderType) { - if ( orderType == null ) { - return ExternalOrderType.DEFAULT; - } - - ExternalOrderType externalOrderType_; - - switch ( orderType ) { - case STANDARD: externalOrderType_ = null; - break; - case RETAIL: externalOrderType_ = ExternalOrderType.RETAIL; - break; - case B2B: externalOrderType_ = ExternalOrderType.B2B; - break; - default: externalOrderType_ = ExternalOrderType.SPECIAL; - } - - return externalOrderType_; - } -} ----- -==== - -*Note:* MapStruct would have refrained from mapping the `RETAIL` and `B2B` when `` was used instead of ``. - - -[WARNING] -==== -The mapping of enum to enum via the `@Mapping` annotation is *DEPRECATED*. It will be removed from future versions of MapStruct. Please adapt existing enum mapping methods to make use of `@ValueMapping` instead. -==== - - -[[object-factories]] -== Object factories - -By default, the generated code for mapping one bean type into another or updating a bean will call the default constructor to instantiate the target type. - -Alternatively you can plug in custom object factories which will be invoked to obtain instances of the target type. One use case for this is JAXB which creates `ObjectFactory` classes for obtaining new instances of schema types. - -To make use of custom factories register them via `@Mapper#uses()` as described in <>, or implement them directly in your mapper. When creating the target object of a bean mapping, MapStruct will look for a parameterless method, a method annotated with `@ObjectFactory`, or a method with only one `@TargetType` parameter that returns the required target type and invoke this method instead of calling the default constructor: - -.Custom object factories -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class DtoFactory { - - public CarDto createCarDto() { - return // ... custom factory logic - } -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class EntityFactory { - - public T createEntity(@TargetType Class entityClass) { - return // ... custom factory logic - } -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(uses= { DtoFactory.class, EntityFactory.class } ) -public interface CarMapper { - - CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); - - CarDto carToCarDto(Car car); - - Car carDtoToCar(CarDto carDto); -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -public class CarMapperImpl implements CarMapper { - - private final DtoFactory dtoFactory = new DtoFactory(); - - private final EntityFactory entityFactory = new EntityFactory(); - - @Override - public CarDto carToCarDto(Car car) { - if ( car == null ) { - return null; - } - - CarDto carDto = dtoFactory.createCarDto(); - - //map properties... - - return carDto; - } - - @Override - public Car carDtoToCar(CarDto carDto) { - if ( carDto == null ) { - return null; - } - - Car car = entityFactory.createEntity( Car.class ); - - //map properties... - - return car; - } -} ----- -==== - -.Custom object factories with update methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(uses = { DtoFactory.class, EntityFactory.class, CarMapper.class } ) -public interface OwnerMapper { - - OwnerMapper INSTANCE = Mappers.getMapper( OwnerMapper.class ); - - void updateOwnerDto(Owner owner, @MappingTarget OwnerDto ownerDto); - - void updateOwner(OwnerDto ownerDto, @MappingTarget Owner owner); -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -//GENERATED CODE -public class OwnerMapperImpl implements OwnerMapper { - - private final DtoFactory dtoFactory = new DtoFactory(); - - private final EntityFactory entityFactory = new EntityFactory(); - - private final OwnerMapper ownerMapper = Mappers.getMapper( OwnerMapper.class ); - - @Override - public void updateOwnerDto(Owner owner, @MappingTarget OwnerDto ownerDto) { - if ( owner == null ) { - return; - } - - if ( owner.getCar() != null ) { - if ( ownerDto.getCar() == null ) { - ownerDto.setCar( dtoFactory.createCarDto() ); - } - // update car within ownerDto - } - else { - ownerDto.setCar( null ); - } - - // updating other properties - } - - @Override - public void updateOwner(OwnerDto ownerDto, @MappingTarget Owner owner) { - if ( ownerDto == null ) { - return; - } - - if ( ownerDto.getCar() != null ) { - if ( owner.getCar() == null ) { - owner.setCar( entityFactory.createEntity( Car.class ) ); - } - // update car within owner - } - else { - owner.setCar( null ); - } - - // updating other properties - } -} ----- -==== - -In addition, annotating a factory method with `@ObjectFactory` lets you gain access to the mapping sources. -Source objects can be added as parameters in the same way as for mapping method. The `@ObjectFactory` -annotation is necessary to let MapStruct know that the given method is only a factory method. - -.Custom object factories with `@ObjectFactory` - -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class DtoFactory { - - @ObjectFactory - public CarDto createCarDto(Car car) { - return // ... custom factory logic - } -} ----- -==== - - -== Advanced mapping options -This chapter describes several advanced options which allow to fine-tune the behavior of the generated mapping code as needed. - -[[default-values-and-constants]] -=== Default values and constants - -Default values can be specified to set a predefined value to a target property if the corresponding source property is `null`. Constants can be specified to set such a predefined value in any case. Default values and constants are specified as String values. When the target type is a primitive or a boxed type, the String value is taken literal. Bit / octal / decimal / hex patterns are allowed in such case as long as they are a valid literal. -In all other cases, constant or default values are subject to type conversion either via built-in conversions or the invocation of other mapping methods in order to match the type required by the target property. - -A mapping with a constant must not include a reference to a source property. The following example shows some mappings using default values and constants: - -.Mapping method with default values and constants -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(uses = StringListMapper.class) -public interface SourceTargetMapper { - - SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - - @Mappings( { - @Mapping(target = "stringProperty", source = "stringProp", defaultValue = "undefined"), - @Mapping(target = "longProperty", source = "longProp", defaultValue = "-1"), - @Mapping(target = "stringConstant", constant = "Constant Value"), - @Mapping(target = "integerConstant", constant = "14"), - @Mapping(target = "longWrapperConstant", constant = "3001"), - @Mapping(target = "dateConstant", dateFormat = "dd-MM-yyyy", constant = "09-01-2014"), - @Mapping(target = "stringListConstants", constant = "jack-jill-tom") - } ) - Target sourceToTarget(Source s); -} ----- -==== - -If `s.getStringProp() == null`, then the target property `stringProperty` will be set to `"undefined"` instead of applying the value from `s.getStringProp()`. If `s.getLongProperty() == null`, then the target property `longProperty` will be set to `-1`. -The String `"Constant Value"` is set as is to the target property `stringConstant`. The value `"3001"` is type-converted to the `Long` (wrapper) class of target property `longWrapperConstant`. Date properties also require a date format. The constant `"jack-jill-tom"` demonstrates how the hand-written class `StringListMapper` is invoked to map the dash-separated list into a `List`. - -[[expressions]] -=== Expressions - -By means of Expressions it will be possible to include constructs from a number of languages. - -Currently only Java is supported as a language. This feature is e.g. useful to invoke constructors. The entire source object is available for usage in the expression. Care should be taken to insert only valid Java code: MapStruct will not validate the expression at generation-time, but errors will show up in the generated classes during compilation. - -The example below demonstrates how two source properties can be mapped to one target: - -.Mapping method using an expression -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface SourceTargetMapper { - - SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - - @Mapping(target = "timeAndFormat", - expression = "java( new org.sample.TimeAndFormat( s.getTime(), s.getFormat() ) )") - Target sourceToTarget(Source s); -} ----- -==== - -The example demonstrates how the source properties `time` and `format` are composed into one target property `TimeAndFormat`. Please note that the fully qualified package name is specified because MapStruct does not take care of the import of the `TimeAndFormat` class (unless it's used otherwise explicitly in the `SourceTargetMapper`). This can be resolved by defining `imports` on the `@Mapper` annotation. - -.Declaring an import -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -imports org.sample.TimeAndFormat; - -@Mapper( imports = TimeAndFormat.class ) -public interface SourceTargetMapper { - - SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - - @Mapping(target = "timeAndFormat", - expression = "java( new TimeAndFormat( s.getTime(), s.getFormat() ) )") - Target sourceToTarget(Source s); -} ----- -==== - -[[default-expressions]] -=== Default Expressions - -Default expressions are a combination of default values and expressions. They will only be used when the source attribute is `null`. - -The same warnings and restrictions apply to default expressions that apply to expressions. Only Java is supported, and MapStruct will not validate the expression at generation-time. - -The example below demonstrates how two source properties can be mapped to one target: - -.Mapping method using a default expression -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -imports java.util.UUID; - -@Mapper( imports = UUID.class ) -public interface SourceTargetMapper { - - SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - - @Mapping(target="id", source="sourceId", defaultExpression = "java( UUID.randomUUID().toString() )") - Target sourceToTarget(Source s); -} ----- -==== - -The example demonstrates how to use defaultExpression to set an `ID` field if the source field is null, this could be used to take the existing `sourceId` from the source object if it is set, or create a new `Id` if it isn't. Please note that the fully qualified package name is specified because MapStruct does not take care of the import of the `UUID` class (unless it’s used otherwise explicitly in the `SourceTargetMapper`). This can be resolved by defining imports on the @Mapper annotation ((see <>). - -[[determining-result-type]] -=== Determining the result type - -When result types have an inheritance relation, selecting either mapping method (`@Mapping`) or a factory method (`@BeanMapping`) can become ambiguous. Suppose an Apple and a Banana, which are both specializations of Fruit. - -.Specifying the result type of a bean mapping method -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper( uses = FruitFactory.class ) -public interface FruitMapper { - - @BeanMapping( resultType = Apple.class ) - Fruit map( FruitDto source ); - -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class FruitFactory { - - public Apple createApple() { - return new Apple( "Apple" ); - } - - public Banana createBanana() { - return new Banana( "Banana" ); - } -} ----- -==== - -So, which `Fruit` must be factorized in the mapping method `Fruit map(FruitDto source);`? A `Banana` or an `Apple`? Here's were the `@BeanMapping#resultType` comes in handy. It controls the factory method to select, or in absence of a factory method, the return type to create. - -[TIP] -==== -The same mechanism is present on mapping: `@Mapping#resultType` and works like you expect it would: it selects the mapping method with the desired result type when present. -==== - -[TIP] -==== -The mechanism is also present on iterable mapping and map mapping. `@IterableMapping#elementTargetType` is used to select the mapping method with the desired element in the resulting `Iterable`. For the `@MapMapping` a similar purpose is served by means of `#MapMapping#keyTargetType` and `MapMapping#valueTargetType`. -==== - -[[mapping-result-for-null-arguments]] -=== Controlling mapping result for 'null' arguments - -MapStruct offers control over the object to create when the source argument of the mapping method equals `null`. By default `null` will be returned. - -However, by specifying `nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT` on `@BeanMapping`, `@IterableMapping`, `@MapMapping`, or globally on `@Mapper` or `@MappingConfig`, the mapping result can be altered to return empty *default* values. This means for: - -* *Bean mappings*: an 'empty' target bean will be returned, with the exception of constants and expressions, they will be populated when present. -* *Primitives*: the default values for primitives will be returned, e.g. `false` for `boolean` or `0` for `int`. -* *Iterables / Arrays*: an empty iterable will be returned. -* *Maps*: an empty map will be returned. - -The strategy works in a hierarchical fashion. Setting `nullValueMappingStrategy` on mapping method level will override `@Mapper#nullValueMappingStrategy`, and `@Mapper#nullValueMappingStrategy` will override `@MappingConfig#nullValueMappingStrategy`. - - -[[checking-source-property-for-null-arguments]] -=== Controlling checking result for 'null' properties in bean mapping - -MapStruct offers control over when to generate a `null` check. By default (`nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION`) a `null` check will be generated for: - -* direct setting of source value to target value when target is primitive and source is not. -* applying type conversion and then: -.. calling the setter on the target. -.. calling another type conversion and subsequently calling the setter on the target. -.. calling a mapping method and subsequently calling the setter on the target. - -First calling a mapping method on the source property is not protected by a null check. Therefor generated mapping methods will do a null check prior to carrying out mapping on a source property. Handwritten mapping methods must take care of null value checking. They have the possibility to add 'meaning' to `null`. For instance: mapping `null` to a default value. - -The option `nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS` will always include a null check when source is non primitive, unless a source presence checker is defined on the source bean. - -The strategy works in a hierarchical fashion. `@Mapper#nullValueCheckStrategy` will override `@MappingConfig#nullValueCheckStrategy`. - -[[source-presence-check]] -=== Source presence checking -Some frameworks generate bean properties that have a source presence checker. Often this is in the form of a method `hasXYZ`, `XYZ` being a property on the source bean in a bean mapping method. MapStruct will call this `hasXYZ` instead of performing a `null` check when it finds such `hasXYZ` method. - -[TIP] -==== -The source presence checker name can be changed in the MapStruct service provider interface (SPI). It can also be deactivated in this way. -==== - -[[exceptions]] -=== Exceptions - -Calling applications may require handling of exceptions when calling a mapping method. These exceptions could be thrown by hand-written logic and by the generated built-in mapping methods or type-conversions of MapStruct. When the calling application requires handling of exceptions, a throws clause can be defined in the mapping method: - -.Mapper using custom method declaring checked exception -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(uses = HandWritten.class) -public interface CarMapper { - - CarDto carToCarDto(Car car) throws GearException; -} ----- -==== - -The hand written logic might look like this: - -.Custom mapping method declaring checked exception -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class HandWritten { - - private static final String[] GEAR = {"ONE", "TWO", "THREE", "OVERDRIVE", "REVERSE"}; - - public String toGear(Integer gear) throws GearException, FatalException { - if ( gear == null ) { - throw new FatalException("null is not a valid gear"); - } - - if ( gear < 0 && gear > GEAR.length ) { - throw new GearException("invalid gear"); - } - return GEAR[gear]; - } -} ----- -==== - -MapStruct now, wraps the `FatalException` in a `try-catch` block and rethrows an unchecked `RuntimeException`. MapStruct delegates handling of the `GearException` to the application logic because it is defined as throws clause in the `carToCarDto` method: - -.try-catch block in generated implementation -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -// GENERATED CODE -@Override -public CarDto carToCarDto(Car car) throws GearException { - if ( car == null ) { - return null; - } - - CarDto carDto = new CarDto(); - try { - carDto.setGear( handWritten.toGear( car.getGear() ) ); - } - catch ( FatalException e ) { - throw new RuntimeException( e ); - } - - return carDto; -} ----- -==== - -Some **notes** on null checks. MapStruct does provide null checking only when required: when applying type-conversions or constructing a new type by invoking its constructor. This means that the user is responsible in hand-written code for returning valid non-null objects. Also null objects can be handed to hand-written code, since MapStruct does not want to make assumptions on the meaning assigned by the user to a null object. Hand-written code has to deal with this. - -== Reusing mapping configurations - -This chapter discusses different means of reusing mapping configurations for several mapping methods: "inheritance" of configuration from other methods and sharing central configuration between multiple mapper types. - -[[mapping-configuration-inheritance]] -=== Mapping configuration inheritance - -Method-level configuration annotations such as `@Mapping`, `@BeanMapping`, `@IterableMapping`, etc., can be *inherited* from one mapping method to a *similar* method using the annotation `@InheritConfiguration`: - -.Update method inheriting its configuration -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mapping(target = "numberOfSeats", source = "seatCount") - Car carDtoToCar(CarDto car); - - @InheritConfiguration - void carDtoIntoCar(CarDto carDto, @MappingTarget Car car); -} ----- -==== - -The example above declares a mapping method `carDtoToCar()` with a configuration to define how the property `numberOfSeats` in the type `Car` shall be mapped. The update method that performs the mapping on an existing instance of `Car` needs the same configuration to successfully map all properties. Declaring `@InheritConfiguration` on the method lets MapStruct search for inheritance candidates to apply the annotations of the method that is inherited from. - -One method *A* can inherit the configuration from another method *B* if all types of *A* (source types and result type) are assignable to the corresponding types of *B*. - -Methods that are considered for inheritance need to be defined in the current mapper, a super class/interface, or in the shared configuration interface (as described in <>). - -In case more than one method is applicable as source for the inheritance, the method name must be specified within the annotation: `@InheritConfiguration( name = "carDtoToCar" )`. - -A method can use `@InheritConfiguration` and override or amend the configuration by additionally applying `@Mapping`, `@BeanMapping`, etc. - -[NOTE] -==== -`@InheritConfiguration` cannot refer to methods in a used mapper. -==== - -[[inverse-mappings]] -=== Inverse mappings - -In case of bi-directional mappings, e.g. from entity to DTO and from DTO to entity, the mapping rules for the forward method and the reverse method are often similar and can simply be inversed by switching `source` and `target`. - -Use the annotation `@InheritInverseConfiguration` to indicate that a method shall inherit the inverse configuration of the corresponding reverse method. - -.Inverse mapping method inheriting its configuration and ignoring some of them -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface CarMapper { - - @Mapping(source = "numberOfSeats", target = "seatCount") - CarDto carToDto(Car car); - - @InheritInverseConfiguration - @Mapping(target = "numberOfSeats", ignore = true) - Car carDtoToCar(CarDto carDto); -} ----- -==== - -Here the `carDtoToCar()` method is the reverse mapping method for `carToDto()`. Note that any attribute mappings from `carToDto()` will be applied to the corresponding reverse mapping method as well. They are automatically reversed and copied to the method with the `@InheritInverseConfiguration` annotation. - -Specific mappings from the inversed method can (optionally) be overridden by `ignore`, `expression` or `constant` in the mapping, e.g. like this: `@Mapping(target = "numberOfSeats", ignore=true)`. - -A method *A* is considered a *reverse* method of a method *B*, if the result type of *A* is the *same* as the single source type of *B* and if the single source type of *A* is the *same* as the result type of *B*. - -Methods that are considered for inverse inheritance need to be defined in the current mapper, a super class/interface. - -If multiple methods qualify, the method from which to inherit the configuration needs to be specified using the `name` property like this: `@InheritInverseConfiguration(name = "carToDto")`. - -`@InheritConfiguration` takes, in case of conflict precedence over `@InheritInverseConfiguration`. - -Configurations are inherited transitively. So if method `C` defines a mapping `@Mapping( target = "x", ignore = true)`, `B` defines a mapping `@Mapping( target = "y", ignore = true)`, then if `A` inherits from `B` inherits from `C`, `A` will inherit mappings for both property `x` and `y`. - -Expressions and constants are excluded (silently ignored) in `@InheritInverseConfiguration`. - -Reverse mapping of nested source properties is experimental as of the 1.1.0.Beta2 release. Reverse mapping will take place automatically when the source property name and target property name are identical. Otherwise, `@Mapping` should specify both the target name and source name. In all cases, a suitable mapping method needs to be in place for the reverse mapping. - -[NOTE] -==== -`@InheritConfiguration` or `@InheritInverseConfiguration` cannot refer to methods in a used mapper. -==== - -[[shared-configurations]] -=== Shared configurations - -MapStruct offers the possibility to define a shared configuration by pointing to a central interface annotated with `@MapperConfig`. For a mapper to use the shared configuration, the configuration interface needs to be defined in the `@Mapper#config` property. - -The `@MapperConfig` annotation has the same attributes as the `@Mapper` annotation. Any attributes not given via `@Mapper` will be inherited from the shared configuration. Attributes specified in `@Mapper` take precedence over the attributes specified via the referenced configuration class. List properties such as `uses` are simply combined: - -.Mapper configuration class and mapper using it -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@MapperConfig( - uses = CustomMapperViaMapperConfig.class, - unmappedTargetPolicy = ReportingPolicy.ERROR -) -public interface CentralConfig { -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(config = CentralConfig.class, uses = { CustomMapperViaMapper.class } ) -// Effective configuration: -// @Mapper( -// uses = { CustomMapperViaMapper.class, CustomMapperViaMapperConfig.class }, -// unmappedTargetPolicy = ReportingPolicy.ERROR -// ) -public interface SourceTargetMapper { - ... -} - ----- -==== - -The interface holding the `@MapperConfig` annotation may also declare *prototypes* of mapping methods that can be used to inherit method-level mapping annotations from. Such prototype methods are not meant to be implemented or used as part of the mapper API. - -.Mapper configuration class with prototype methods -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@MapperConfig( - uses = CustomMapperViaMapperConfig.class, - unmappedTargetPolicy = ReportingPolicy.ERROR, - mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG -) -public interface CentralConfig { - - // Not intended to be generated, but to carry inheritable mapping annotations: - @Mapping(target = "primaryKey", source = "technicalKey") - BaseEntity anyDtoToEntity(BaseDto dto); -} ----- -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper(config = CentralConfig.class, uses = { CustomMapperViaMapper.class } ) -public interface SourceTargetMapper { - - @Mapping(target = "numberOfSeats", source = "seatCount") - // additionally inherited from CentralConfig, because Car extends BaseEntity and CarDto extends BaseDto: - // @Mapping(target = "primaryKey", source = "technicalKey") - Car toCar(CarDto car) -} ----- -==== - -The attributes `@Mapper#mappingInheritanceStrategy()` / `@MapperConfig#mappingInheritanceStrategy()` configure when the method-level mapping configuration annotations are inherited from prototype methods in the interface to methods in the mapper: - -* `EXPLICIT` (default): the configuration will only be inherited, if the target mapping method is annotated with `@InheritConfiguration` and the source and target types are assignable to the corresponding types of the prototype method, all as described in <>. -* `AUTO_INHERIT_FROM_CONFIG`: the configuration will be inherited automatically, if the source and target types of the target mapping method are assignable to the corresponding types of the prototype method. If multiple prototype methods match, the ambiguity must be resolved using `@InheritConfiguration(name = ...)` which will cause `AUTO_INHERIT_FROM_CONFIG` to be ignored. -* `AUTO_INHERIT_REVERSE_FROM_CONFIG`: the inverse configuration will be inherited automatically, if the source and target types of the target mapping method are assignable to the corresponding types of the prototype method. If multiple prototype methods match, the ambiguity must be resolved using `@InheritInverseConfiguration(name = ...)` which will cause ``AUTO_INHERIT_REVERSE_FROM_CONFIG` to be ignored. -* `AUTO_INHERIT_ALL_FROM_CONFIG`: both the configuration and the inverse configuration will be inherited automatically. The same rules apply as for `AUTO_INHERIT_FROM_CONFIG` or `AUTO_INHERIT_REVERSE_FROM_CONFIG`. - -== Customizing mappings - -Sometimes it's needed to apply custom logic before or after certain mapping methods. MapStruct provides two ways for doing so: decorators which allow for a type-safe customization of specific mapping methods and the before-mapping and after-mapping lifecycle methods which allow for a generic customization of mapping methods with given source or target types. - -[[customizing-mappers-using-decorators]] -=== Mapping customization with decorators - -In certain cases it may be required to customize a generated mapping method, e.g. to set an additional property in the target object which can't be set by a generated method implementation. MapStruct supports this requirement using decorators. - -[TIP] -When working with the component model `cdi`, use https://docs.jboss.org/cdi/spec/1.0/html/decorators.html[CDI decorators] with MapStruct mappers instead of the `@DecoratedWith` annotation described here. - -To apply a decorator to a mapper class, specify it using the `@DecoratedWith` annotation. - -.Applying a decorator -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -@DecoratedWith(PersonMapperDecorator.class) -public interface PersonMapper { - - PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class ); - - PersonDto personToPersonDto(Person person); - - AddressDto addressToAddressDto(Address address); -} ----- -==== - -The decorator must be a sub-type of the decorated mapper type. You can make it an abstract class which allows to only implement those methods of the mapper interface which you want to customize. For all non-implemented methods, a simple delegation to the original mapper will be generated using the default generation routine. - -The `PersonMapperDecorator` shown below customizes the `personToPersonDto()`. It sets an additional attribute which is not present in the source type of the mapping. The `addressToAddressDto()` method is not customized. - -.Implementing a decorator -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public abstract class PersonMapperDecorator implements PersonMapper { - - private final PersonMapper delegate; - - public PersonMapperDecorator(PersonMapper delegate) { - this.delegate = delegate; - } - - @Override - public PersonDto personToPersonDto(Person person) { - PersonDto dto = delegate.personToPersonDto( person ); - dto.setFullName( person.getFirstName() + " " + person.getLastName() ); - return dto; - } -} ----- -==== - -The example shows how you can optionally inject a delegate with the generated default implementation and use this delegate in your customized decorator methods. - -For a mapper with `componentModel = "default"`, define a constructor with a single parameter which accepts the type of the decorated mapper. - -When working with the component models `spring` or `jsr330`, this needs to be handled differently. - -[[decorators-with-spring]] -==== Decorators with the Spring component model - -When using `@DecoratedWith` on a mapper with component model `spring`, the generated implementation of the original mapper is annotated with the Spring annotation `@Qualifier("delegate")`. To autowire that bean in your decorator, add that qualifier annotation as well: - -.Spring-based decorator -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public abstract class PersonMapperDecorator implements PersonMapper { - - @Autowired - @Qualifier("delegate") - private PersonMapper delegate; - - @Override - public PersonDto personToPersonDto(Person person) { - PersonDto dto = delegate.personToPersonDto( person ); - dto.setName( person.getFirstName() + " " + person.getLastName() ); - - return dto; - } - } ----- -==== - -The generated class that extends the decorator is annotated with Spring's `@Primary` annotation. To autowire the decorated mapper in the application, nothing special needs to be done: - -.Using a decorated mapper -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Autowired -private PersonMapper personMapper; // injects the decorator, with the injected original mapper ----- -==== - -[[decorators-with-jsr-330]] -==== Decorators with the JSR 330 component model - -JSR 330 doesn't specify qualifiers and only allows to specifically name the beans. Hence, the generated implementation of the original mapper is annotated with `@Named("fully-qualified-name-of-generated-implementation")` (please note that when using a decorator, the class name of the mapper implementation ends with an underscore). To inject that bean in your decorator, add the same annotation to the delegate field (e.g. by copy/pasting it from the generated class): - -.JSR 330 based decorator -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public abstract class PersonMapperDecorator implements PersonMapper { - - @Inject - @Named("org.examples.PersonMapperImpl_") - private PersonMapper delegate; - - @Override - public PersonDto personToPersonDto(Person person) { - PersonDto dto = delegate.personToPersonDto( person ); - dto.setName( person.getFirstName() + " " + person.getLastName() ); - - return dto; - } -} ----- -==== - -Unlike with the other component models, the usage site must be aware if a mapper is decorated or not, as for decorated mappers, the parameterless `@Named` annotation must be added to select the decorator to be injected: - -.Using a decorated mapper with JSR 330 -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Inject -@Named -private PersonMapper personMapper; // injects the decorator, with the injected original mapper ----- -==== - -[WARNING] -==== -`@DecoratedWith` in combination with component model `jsr330` is considered experimental as of the 1.0.0.CR2 release. The way the original mapper is referenced in the decorator or the way the decorated mapper is injected in the application code might still change. -==== - -[[customizing-mappings-with-before-and-after]] -=== Mapping customization with before-mapping and after-mapping methods - -Decorators may not always fit the needs when it comes to customizing mappers. For example, if you need to perform the customization not only for a few selected methods, but for all methods that map specific super-types: in that case, you can use *callback methods* that are invoked before the mapping starts or after the mapping finished. - -Callback methods can be implemented in the abstract mapper itself, in a type reference in `Mapper#uses`, or in a type used as `@Context` parameter. - -.Mapper with @BeforeMapping and @AfterMapping hooks -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public abstract class VehicleMapper { - - @BeforeMapping - protected void flushEntity(AbstractVehicle vehicle) { - // I would call my entity manager's flush() method here to make sure my entity - // is populated with the right @Version before I let it map into the DTO - } - - @AfterMapping - protected void fillTank(AbstractVehicle vehicle, @MappingTarget AbstractVehicleDto result) { - result.fuelUp( new Fuel( vehicle.getTankCapacity(), vehicle.getFuelType() ) ); - } - - public abstract CarDto toCarDto(Car car); -} - -// Generates something like this: -public class VehicleMapperImpl extends VehicleMapper { - - public CarDto toCarDto(Car car) { - flushEntity( car ); - - if ( car == null ) { - return null; - } - - CarDto carDto = new CarDto(); - // attributes mapping ... - - fillTank( car, carDto ); - - return carDto; - } -} ----- -==== - -If the `@BeforeMapping` / `@AfterMapping` method has parameters, the method invocation is only generated if the return type of the method (if non-`void`) is assignable to the return type of the mapping method and all parameters can be *assigned* by the source or target parameters of the mapping method: - -* A parameter annotated with `@MappingTarget` is populated with the target instance of the mapping. -* A parameter annotated with `@TargetType` is populated with the target type of the mapping. -* Parameters annotated with `@Context` are populated with the context parameters of the mapping method. -* Any other parameter is populated with a source parameter of the mapping. - -For non-`void` methods, the return value of the method invocation is returned as the result of the mapping method if it is not `null`. - -As with mapping methods, it is possible to specify type parameters for before/after-mapping methods. - -.Mapper with @AfterMapping hook that returns a non-null value -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public abstract class VehicleMapper { - - @PersistenceContext - private EntityManager entityManager; - - @AfterMapping - protected T attachEntity(@MappingTarget T entity) { - return entityManager.merge(entity); - } - - public abstract CarDto toCarDto(Car car); -} - -// Generates something like this: -public class VehicleMapperImpl extends VehicleMapper { - - public CarDto toCarDto(Car car) { - if ( car == null ) { - return null; - } - - CarDto carDto = new CarDto(); - // attributes mapping ... - - CarDto target = attachEntity( carDto ); - if ( target != null ) { - return target; - } - - return carDto; - } -} ----- -==== - -All before/after-mapping methods that *can* be applied to a mapping method *will* be used. <> can be used to further control which methods may be chosen and which not. For that, the qualifier annotation needs to be applied to the before/after-method and referenced in `BeanMapping#qualifiedBy` or `IterableMapping#qualifiedBy`. - -The order of the method invocation is determined primarily by their variant: - -1. `@BeforeMapping` methods without an `@MappingTarget` parameter are called before any null-checks on source - parameters and constructing a new target bean. -2. `@BeforeMapping` methods with an `@MappingTarget` parameter are called after constructing a new target bean. -3. `@AfterMapping` methods are called at the end of the mapping method before the last `return` statement. - -Within those groups, the method invocations are ordered by their location of definition: - -1. Methods declared on `@Context` parameters, ordered by the parameter order. -2. Methods implemented in the mapper itself. -3. Methods from types referenced in `Mapper#uses()`, in the order of the type declaration in the annotation. -4. Methods declared in one type are used after methods declared in their super-type. - -*Important:* the order of methods declared within one type can not be guaranteed, as it depends on the compiler and the processing environment implementation. - - -[[using-spi]] -== Using the MapStruct SPI -=== Custom Accessor Naming Strategy - -MapStruct offers the possibility to override the `AccessorNamingStrategy` via the Service Provide Interface (SPI). A nice example is the use of the fluent API on the source object `GolfPlayer` and `GolfPlayerDto` below. - -.Source object GolfPlayer with fluent API. -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class GolfPlayer { - - private double handicap; - private String name; - - public double handicap() { - return handicap; - } - - public GolfPlayer withHandicap(double handicap) { - this.handicap = handicap; - return this; - } - - public String name() { - return name; - } - - public GolfPlayer withName(String name) { - this.name = name; - return this; - } -} ----- -==== - -.Source object GolfPlayerDto with fluent API. -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -public class GolfPlayerDto { - - private double handicap; - private String name; - - public double handicap() { - return handicap; - } - - public GolfPlayerDto withHandicap(double handicap) { - this.handicap = handicap; - return this; - } - - public String name() { - return name; - } - - public GolfPlayerDto withName(String name) { - this.name = name; - return this - } -} ----- -==== - -We want `GolfPlayer` to be mapped to a target object `GolfPlayerDto` similar like we 'always' do this: - -.Source object with fluent API. -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -@Mapper -public interface GolfPlayerMapper { - - GolfPlayerMapper INSTANCE = Mappers.getMapper( GolfPlayerMapper.class ); - - GolfPlayerDto toDto(GolfPlayer player); - - GolfPlayer toPlayer(GolfPlayerDto player); - -} ----- -==== - -This can be achieved with implementing the SPI `org.mapstruct.ap.spi.AccessorNamingStrategy` as in the following example. Here's an implemented `org.mapstruct.ap.spi.AccessorNamingStrategy`: - -.CustomAccessorNamingStrategy -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -/** - * A custom {@link AccessorNamingStrategy} recognizing getters in the form of {@code property()} and setters in the - * form of {@code withProperty(value)}. - */ -public class CustomAccessorNamingStrategy extends DefaultAccessorNamingStrategy { - - @Override - public boolean isGetterMethod(ExecutableElement method) { - String methodName = method.getSimpleName().toString(); - return !methodName.startsWith( "with" ) && method.getReturnType().getKind() != TypeKind.VOID; - } - - @Override - public boolean isSetterMethod(ExecutableElement method) { - String methodName = method.getSimpleName().toString(); - return methodName.startsWith( "with" ) && methodName.length() > 4; - } - - @Override - public String getPropertyName(ExecutableElement getterOrSetterMethod) { - String methodName = getterOrSetterMethod.getSimpleName().toString(); - return Introspector.decapitalize( methodName.startsWith( "with" ) ? methodName.substring( 4 ) : methodName ); - } -} ----- -==== -The `CustomAccessorNamingStrategy` makes use of the `DefaultAccessorNamingStrategy` (also available in mapstruct-processor) and relies on that class to leave most of the default behaviour unchanged. - -To use a custom SPI implementation, it must be located in a separate JAR file together with the file `META-INF/services/org.mapstruct.ap.spi.AccessorNamingStrategy` with the fully qualified name of your custom implementation as content (e.g. `org.mapstruct.example.CustomAccessorNamingStrategy`). This JAR file needs to be added to the annotation processor classpath (i.e. add it next to the place where you added the mapstruct-processor jar). - -[TIP] -Fore more details: The example above is present in our examples repository (https://github.com/mapstruct/mapstruct-examples). - -[mapping-exclusion-provider] -=== Mapping Exclusion Provider - -MapStruct offers the possibility to override the `MappingExclusionProvider` via the Service Provider Interface (SPI). -A nice example is to not allow MapStruct to create an automatic sub-mapping for a certain type, -i.e. MapStruct will not try to generate an automatic sub-mapping method for an excluded type. - -[NOTE] -==== -The `DefaultMappingExclusionProvider` will exclude all types under the `java` or `javax` packages. -This means that MapStruct will not try to generate an automatic sub-mapping method between some custom type and some type declared in the Java class library. -==== - -.Source object -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -include::{processor-ap-test}/nestedbeans/exclusions/custom/Source.java[tag=documentation] ----- -==== - -.Target object -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -include::{processor-ap-test}/nestedbeans/exclusions/custom/Target.java[tag=documentation] ----- -==== - -.Mapper definition -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -include::{processor-ap-test}/nestedbeans/exclusions/custom/ErroneousCustomExclusionMapper.java[tag=documentation] ----- -==== - -We want to exclude the `NestedTarget` from the automatic sub-mapping method generation. - -.CustomMappingExclusionProvider -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -include::{processor-ap-test}/nestedbeans/exclusions/custom/CustomMappingExclusionProvider.java[tag=documentation] ----- -==== - -To use a custom SPI implementation, it must be located in a separate JAR file -together with the file `META-INF/services/org.mapstruct.ap.spi.MappingExclusionProvider` with the fully qualified name of your custom implementation as content -(e.g. `org.mapstruct.example.CustomMappingExclusionProvider`). -This JAR file needs to be added to the annotation processor classpath -(i.e. add it next to the place where you added the mapstruct-processor jar). - - -[[custom-builder-provider]] -=== Custom Builder Provider - -MapStruct offers the possibility to override the `DefaultProvider` via the Service Provider Interface (SPI). -A nice example is to provide support for a custom builder strategy. - -.Custom Builder Provider which disables Builder support -==== -[source, java, linenums] -[subs="verbatim,attributes"] ----- -include::{processor-ap-main}/spi/NoOpBuilderProvider.java[tag=documentation] ----- -==== +include::chapter-14-third-party-api-integration.asciidoc[] \ No newline at end of file diff --git a/etc/travis-settings.xml b/etc/ci-settings.xml similarity index 100% rename from etc/travis-settings.xml rename to etc/ci-settings.xml diff --git a/etc/license.txt b/etc/license.txt index 2cc3d75aa3..66af6edf79 100644 --- a/etc/license.txt +++ b/etc/license.txt @@ -1,16 +1,3 @@ - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. +Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. +Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/etc/toolchains-cloudbees-jenkins.xml b/etc/toolchains-cloudbees-jenkins.xml deleted file mode 100644 index e6ce86e063..0000000000 --- a/etc/toolchains-cloudbees-jenkins.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - jdk - - 1.6 - oracle - jdk1.6 - - - /opt/jdk/jdk1.6.latest - - - - jdk - - 1.7 - oracle - jdk1.7 - - - /opt/jdk/jdk1.7.latest - - - - jdk - - 1.8 - oracle - jdk1.8 - - - /opt/jdk/jdk8.latest - - - - diff --git a/etc/toolchains-example.xml b/etc/toolchains-example.xml deleted file mode 100644 index 08cee8b241..0000000000 --- a/etc/toolchains-example.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - jdk - - 1.6.0_45 - oracle - jdk1.6 - - - C:\Program Files\Java\jdk1.6.0_45 - - - - jdk - - 1.7.0_51 - oracle - jdk1.7 - - - C:\Program Files\Java\jdk1.7.0_51 - - - - jdk - - 1.8.0_11 - oracle - jdk1.8 - - - C:\Program Files\Java\jdk1.8.0_11 - - - - jdk - - 1.9.0 - oracle - jdk1.9 - - - C:\Program Files\Java\jdk1.9.0 - - - diff --git a/etc/toolchains-travis-jenkins.xml b/etc/toolchains-travis-jenkins.xml deleted file mode 100644 index 75ac0de574..0000000000 --- a/etc/toolchains-travis-jenkins.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - jdk - - 1.6 - oracle - jdk1.6 - - - /usr/lib/jvm/java-6-openjdk-amd64/ - - - - jdk - - 1.7 - oracle - jdk1.7 - - - /usr/lib/jvm/java-7-openjdk-amd64/ - - - - jdk - - 1.8 - oracle - jdk1.8 - - - /usr/lib/jvm/java-8-oracle/ - - - - diff --git a/integrationtest/pom.xml b/integrationtest/pom.xml index 2e377915cd..71a61fc2fe 100644 --- a/integrationtest/pom.xml +++ b/integrationtest/pom.xml @@ -1,22 +1,9 @@ @@ -25,7 +12,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml @@ -37,14 +24,22 @@ ${project.version} true + + + + gradle + https://repo.gradle.org/artifactory/libs-releases/ + + true + + + false + + + - - junit - junit - test - org.assertj assertj-core @@ -55,6 +50,34 @@ maven-verifier test + + org.gradle + gradle-test-kit + 5.6.4 + test + + + org.gradle + gradle-tooling-api + 5.6.4 + test + + + commons-io + commons-io + test + + + org.junit.jupiter + junit-jupiter + test + + + org.junit.jupiter + junit-jupiter-engine + test + + @@ -72,14 +95,6 @@ \ - - org.apache.maven.plugins - maven-compiler-plugin - - 1.8 - 1.8 - - org.apache.maven.plugins maven-surefire-plugin @@ -92,19 +107,46 @@ - - org.apache.maven.plugins - maven-checkstyle-plugin - - - check-style - verify - - checkstyle - - - - + + + + jdk-11-or-newer + + [11 + + + + javax.xml.bind + jaxb-api + provided + true + + + + + jdk-21-or-newer + + [21 + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + check-style + verify + + checkstyle + + + + + + + + diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/AutoValueBuilderTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/AutoValueBuilderTest.java deleted file mode 100644 index 3d69d052f9..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/AutoValueBuilderTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Filip Hrisafov - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite(baseDir = "autoValueBuilderTest", - processorTypes = ProcessorSuite.ProcessorType.ALL_WITHOUT_PROCESSOR_PLUGIN) -public class AutoValueBuilderTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/CdiTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/CdiTest.java deleted file mode 100644 index bea73ef70e..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/CdiTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "cdiTest", processorTypes = ProcessorType.ALL ) -public class CdiTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/ExternalBeanJarTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/ExternalBeanJarTest.java deleted file mode 100644 index 87010b9e85..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/ExternalBeanJarTest.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * - * See: https://github.com/mapstruct/mapstruct/issues/1121 - * - * @author Sjaak Derksen - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite(baseDir = "externalbeanjar", processorTypes = ProcessorSuite.ProcessorType.ORACLE_JAVA_8) -public class ExternalBeanJarTest { - -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/FreeBuilderBuilderTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/FreeBuilderBuilderTest.java deleted file mode 100644 index 78b5465c83..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/FreeBuilderBuilderTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Filip Hrisafov - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "freeBuilderBuilderTest", - processorTypes = ProcessorSuite.ProcessorType.ALL_WITHOUT_PROCESSOR_PLUGIN) -public class FreeBuilderBuilderTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationExclusionCliEnhancer.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationExclusionCliEnhancer.java new file mode 100644 index 0000000000..7d397c9499 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationExclusionCliEnhancer.java @@ -0,0 +1,71 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.tests; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.jupiter.api.condition.JRE; +import org.mapstruct.itest.testutil.extension.ProcessorTest; + +/** + * Adds explicit exclusions of test mappers that are known or expected to not work with specific compilers. + * + * @author Andreas Gudian + */ +public final class FullFeatureCompilationExclusionCliEnhancer implements ProcessorTest.CommandLineEnhancer { + @Override + public Collection getAdditionalCommandLineArguments(ProcessorTest.ProcessorType processorType, + JRE currentJreVersion) { + List additionalExcludes = new ArrayList<>(); + + // SPI not working correctly here.. (not picked up) + additionalExcludes.add( "org/mapstruct/ap/test/bugs/_1596/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/bugs/_1801/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/bugs/_3089/*.java" ); + + switch ( currentJreVersion ) { + case JAVA_8: + additionalExcludes.add( "org/mapstruct/ap/test/**/spring/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/cdi/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/annotatewith/deprecated/jdk11/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk17/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk17/**/*.java" ); + if ( processorType == ProcessorTest.ProcessorType.ECLIPSE_JDT ) { + additionalExcludes.add( + "org/mapstruct/ap/test/selection/methodgenerics/wildcards/LifecycleIntersectionMapper.java" ); + } + break; + case JAVA_9: + // TODO find out why this fails: + additionalExcludes.add( "org/mapstruct/ap/test/collection/wildcard/BeanMapper.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk17/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk17/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" ); + break; + case JAVA_11: + additionalExcludes.add( "org/mapstruct/ap/test/**/spring/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk17/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk17/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" ); + break; + case JAVA_17: + additionalExcludes.add( "org/mapstruct/ap/test/**/jdk21/*.java" ); + break; + default: + } + + Collection result = new ArrayList<>(additionalExcludes.size()); + for ( int i = 0; i < additionalExcludes.size(); i++ ) { + result.add( "-DadditionalExclude" + i + "=" + additionalExcludes.get( i ) ); + } + + return result; + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationTest.java deleted file mode 100644 index 46dc4ce6bd..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/FullFeatureCompilationTest.java +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.tests.FullFeatureCompilationTest.CompilationExclusionCliEnhancer; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.CommandLineEnhancer; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * Integration test that compiles all test mappers in the processor-module, excluding all classes that contain one of - * the following in their path/file name: - *
      - *
    • {@code /erronerous/}
    • - *
    • {@code *Erroneous*}
    • - *
    • {@code *Test.java}
    • - *
    • {@code /testutil/}
    • - *
    • possibly more, depending on the processor type - see {@link CompilationExclusionCliEnhancer}
    • - *
    - * - * @author Andreas Gudian - */ -@RunWith(ProcessorSuiteRunner.class) -@ProcessorSuite( - baseDir = "fullFeatureTest", - commandLineEnhancer = CompilationExclusionCliEnhancer.class, - processorTypes = { - ProcessorType.ORACLE_JAVA_6, - ProcessorType.ORACLE_JAVA_7, - ProcessorType.ORACLE_JAVA_8, - ProcessorType.ORACLE_JAVA_9, - ProcessorType.ECLIPSE_JDT_JAVA_6, - ProcessorType.ECLIPSE_JDT_JAVA_7, - ProcessorType.ECLIPSE_JDT_JAVA_8 -}) -public class FullFeatureCompilationTest { - /** - * Adds explicit exclusions of test mappers that are known or expected to not work with specific compilers. - * - * @author Andreas Gudian - */ - public static final class CompilationExclusionCliEnhancer implements CommandLineEnhancer { - @Override - public Collection getAdditionalCommandLineArguments(ProcessorType processorType) { - List additionalExcludes = new ArrayList<>(); - - switch ( processorType ) { - case ORACLE_JAVA_6: - additionalExcludes.add( "org/mapstruct/ap/test/abstractclass/generics/*.java" ); - additionalExcludes.add( "org/mapstruct/ap/test/bugs/_1170/*.java" ); - case ECLIPSE_JDT_JAVA_6: - case ORACLE_JAVA_7: - case ECLIPSE_JDT_JAVA_7: - additionalExcludes.add( "org/mapstruct/ap/test/bugs/_1425/*.java" ); - additionalExcludes.add( "**/java8*/**/*.java" ); - break; - case ORACLE_JAVA_9: - // TODO find out why this fails: - additionalExcludes.add( "org/mapstruct/ap/test/collection/wildcard/BeanMapper.java" ); - break; - default: - } - - Collection result = new ArrayList( additionalExcludes.size() ); - for ( int i = 0; i < additionalExcludes.size(); i++ ) { - result.add( "-DadditionalExclude" + i + "=" + additionalExcludes.get( i ) ); - } - - return result; - } - } -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/GradleIncrementalCompilationTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/GradleIncrementalCompilationTest.java new file mode 100644 index 0000000000..a12af7690f --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/tests/GradleIncrementalCompilationTest.java @@ -0,0 +1,170 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.tests; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Stream; + +import org.apache.commons.io.FileUtils; +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; +import org.gradle.testkit.runner.TaskOutcome; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Named; +import org.junit.jupiter.api.condition.DisabledForJreRange; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS; +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE; +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + *

    This is supposed to be run from the mapstruct root project folder. + * Otherwise, use -Dmapstruct_root=path_to_project. + */ +@DisabledForJreRange(min = JRE.JAVA_11) +class GradleIncrementalCompilationTest { + private static Path rootPath; + private static final String PROJECT_DIR = "integrationtest/src/test/resources/gradleIncrementalCompilationTest"; + private static final String COMPILE_TASK_NAME = "compileJava"; + + @TempDir + private File testBuildDir; + @TempDir + private File testProjectDir; + + private GradleRunner runner; + private File sourceDirectory; + private List compileArgs; // Gradle compile task arguments + + static Stream gradleVersions() { + return Stream.of( + Arguments.of( Named.of( "Gradle 5.0", "5.0" ) ), + Arguments.of( Named.of( "Gradle 6.0", "6.0" ) ) ); + } + + private void replaceInFile(File file, CharSequence target, CharSequence replacement) throws IOException { + String content = FileUtils.readFileToString( file, Charset.defaultCharset() ); + FileUtils.writeStringToFile( file, content.replace( target, replacement ), Charset.defaultCharset() ); + } + + private GradleRunner getRunner(String... additionalArguments) { + List fullArguments = new ArrayList<>(compileArgs); + fullArguments.addAll( Arrays.asList( additionalArguments ) ); + return runner.withArguments( fullArguments ); + } + + private void assertCompileOutcome(BuildResult result, TaskOutcome outcome) { + assertEquals( outcome, result.task( ":" + COMPILE_TASK_NAME ).getOutcome() ); + } + + private void assertRecompiled(BuildResult result, int recompiledCount) { + assertCompileOutcome( result, recompiledCount > 0 ? SUCCESS : UP_TO_DATE ); + assertThat( result.getOutput() ) + .contains( String.format( "Incremental compilation of %d classes completed", recompiledCount ) ); + } + + private List buildCompileArgs() { + // Make Gradle use the temporary build folder by overriding the buildDir property + String buildDirPropertyArg = "-PbuildDir=" + testBuildDir.getAbsolutePath(); + + // Inject the path to the folder containing the mapstruct-processor JAR + String jarDirectoryArg = "-PmapstructRootPath=" + rootPath.toString(); + return Arrays.asList( COMPILE_TASK_NAME, buildDirPropertyArg, jarDirectoryArg ); + } + + @BeforeAll + static void setupClass() { + rootPath = Paths.get( System.getProperty( "mapstruct_root", "." ) ).toAbsolutePath(); + } + + public void setup(String gradleVersion) throws IOException { + if ( !testBuildDir.exists() ) { + testBuildDir.mkdirs(); + } + + if ( !testProjectDir.exists() ) { + testProjectDir.mkdirs(); + } + // Copy test project files to the temp dir + Path gradleProjectPath = rootPath.resolve( PROJECT_DIR ); + FileUtils.copyDirectory( gradleProjectPath.toFile(), testProjectDir ); + compileArgs = buildCompileArgs(); + sourceDirectory = new File( testProjectDir, "src/main/java" ); + runner = GradleRunner.create().withGradleVersion( gradleVersion ).withProjectDir( testProjectDir ); + } + + @ParameterizedTest + @MethodSource("gradleVersions") + void testBuildSucceeds(String gradleVersion) throws IOException { + setup( gradleVersion ); + // Make sure the test build setup actually compiles + BuildResult buildResult = getRunner().build(); + assertCompileOutcome( buildResult, SUCCESS ); + } + + @ParameterizedTest + @MethodSource("gradleVersions") + void testUpToDate(String gradleVersion) throws IOException { + setup( gradleVersion ); + getRunner().build(); + BuildResult secondBuildResult = getRunner().build(); + assertCompileOutcome( secondBuildResult, UP_TO_DATE ); + } + + @ParameterizedTest + @MethodSource("gradleVersions") + void testChangeConstant(String gradleVersion) throws IOException { + setup( gradleVersion ); + getRunner().build(); + // Change return value in class Target + File targetFile = new File( sourceDirectory, "org/mapstruct/itest/gradle/model/Target.java" ); + replaceInFile( targetFile, "original", "changed" ); + BuildResult secondBuildResult = getRunner( "--info" ).build(); + + // 3 classes should be recompiled: Target -> TestMapper -> TestMapperImpl + assertRecompiled( secondBuildResult, 3 ); + } + + @ParameterizedTest + @MethodSource("gradleVersions") + void testChangeTargetField(String gradleVersion) throws IOException { + setup( gradleVersion ); + getRunner().build(); + // Change target field in mapper interface + File mapperFile = new File( sourceDirectory, "org/mapstruct/itest/gradle/lib/TestMapper.java" ); + replaceInFile( mapperFile, "field", "otherField" ); + BuildResult secondBuildResult = getRunner( "--info" ).build(); + + // 2 classes should be recompiled: TestMapper -> TestMapperImpl + assertRecompiled( secondBuildResult, 2 ); + } + + @ParameterizedTest + @MethodSource("gradleVersions") + void testChangeUnrelatedFile(String gradleVersion) throws IOException { + setup( gradleVersion ); + getRunner().build(); + File unrelatedFile = new File( sourceDirectory, "org/mapstruct/itest/gradle/lib/UnrelatedComponent.java" ); + replaceInFile( unrelatedFile, "true", "false" ); + BuildResult secondBuildResult = getRunner( "--info" ).build(); + + // Only the UnrelatedComponent class should be recompiled + assertRecompiled( secondBuildResult, 1 ); + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/ImmutablesBuilderTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/ImmutablesBuilderTest.java deleted file mode 100644 index 2bc395486e..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/ImmutablesBuilderTest.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Filip Hrisafov - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "immutablesBuilderTest", - processorTypes = ProcessorSuite.ProcessorType.ALL_WITHOUT_PROCESSOR_PLUGIN) -public class ImmutablesBuilderTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/Java8Test.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/Java8Test.java deleted file mode 100644 index dd52db731f..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/Java8Test.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "java8Test", processorTypes = ProcessorType.ALL_JAVA_8 ) -public class Java8Test { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/JaxbTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/JaxbTest.java deleted file mode 100644 index b72e5b1146..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/JaxbTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "jaxbTest", processorTypes = ProcessorType.ALL ) -public class JaxbTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/Jsr330Test.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/Jsr330Test.java deleted file mode 100644 index dd82752f4a..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/Jsr330Test.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "jsr330Test", processorTypes = ProcessorType.ALL ) -public class Jsr330Test { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/KotlinFullFeatureCompilationExclusionCliEnhancer.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/KotlinFullFeatureCompilationExclusionCliEnhancer.java new file mode 100644 index 0000000000..b4dddfb308 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/tests/KotlinFullFeatureCompilationExclusionCliEnhancer.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.tests; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.junit.jupiter.api.condition.JRE; +import org.mapstruct.itest.testutil.extension.ProcessorTest; + +/** + * Adds explicit exclusions of test mappers that are known or expected to not work with specific compilers. + * + * @author Filip Hrisafov + */ +public final class KotlinFullFeatureCompilationExclusionCliEnhancer implements ProcessorTest.CommandLineEnhancer { + @Override + public Collection getAdditionalCommandLineArguments(ProcessorTest.ProcessorType processorType, + JRE currentJreVersion) { + List additionalExcludes = new ArrayList<>(); + + + switch ( currentJreVersion ) { + case JAVA_8: + addJdkExclude( additionalExcludes, "jdk17" ); + addJdkExclude( additionalExcludes, "jdk21" ); + break; + case JAVA_11: + addJdkExclude( additionalExcludes, "jdk17" ); + addJdkExclude( additionalExcludes, "jdk21" ); + break; + case JAVA_17: + addJdkExclude( additionalExcludes, "jdk21" ); + break; + default: + } + + Collection result = new ArrayList<>( additionalExcludes.size() ); + for ( int i = 0; i < additionalExcludes.size(); i++ ) { + result.add( "-DadditionalExclude" + i + "=" + additionalExcludes.get( i ) ); + } + + return result; + } + + private static void addJdkExclude(Collection additionalExcludes, String jdk) { + additionalExcludes.add( "org/mapstruct/ap/test/**/kotlin/**/" + jdk + "/**/*.java" ); + additionalExcludes.add( "org/mapstruct/ap/test/**/kotlin/**/" + jdk + "/**/*.kt" ); + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/LombokBuilderTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/LombokBuilderTest.java deleted file mode 100644 index a86a1b805c..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/LombokBuilderTest.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Eric Martineau - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "lombokBuilderTest", - processorTypes = { - ProcessorSuite.ProcessorType.ORACLE_JAVA_6, - ProcessorSuite.ProcessorType.ORACLE_JAVA_7, - ProcessorSuite.ProcessorType.ORACLE_JAVA_8, - ProcessorSuite.ProcessorType.ORACLE_JAVA_9, - } -) -public class LombokBuilderTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/MavenIntegrationTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/MavenIntegrationTest.java new file mode 100644 index 0000000000..042d6ec1da --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/tests/MavenIntegrationTest.java @@ -0,0 +1,231 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.tests; + +import org.junit.jupiter.api.condition.DisabledForJreRange; +import org.junit.jupiter.api.condition.DisabledOnJre; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.mapstruct.itest.testutil.extension.ProcessorTest; + +/** + * @author Filip Hrisafov + */ +@Execution( ExecutionMode.CONCURRENT ) +public class MavenIntegrationTest { + + @ProcessorTest(baseDir = "autoValueBuilderTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC, + ProcessorTest.ProcessorType.ECLIPSE_JDT + }) + void autoValueBuilderTest() { + } + + @ProcessorTest(baseDir = "cdiTest") + void cdiTest() { + } + + /** + * See: https://github.com/mapstruct/mapstruct/issues/1121 + */ + @ProcessorTest(baseDir = "externalbeanjar", processorTypes = ProcessorTest.ProcessorType.JAVAC) + void externalBeanJarTest() { + } + + @ProcessorTest(baseDir = "freeBuilderBuilderTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + void freeBuilderBuilderTest() { + } + + /** + * Integration test that compiles all test mappers in the processor-module, excluding all classes that contain + * one of + * the following in their path/file name: + *

      + *
    • {@code /erronerous/}
    • + *
    • {@code *Erroneous*}
    • + *
    • {@code *Test.java}
    • + *
    • {@code /testutil/}
    • + *
    • possibly more, depending on the processor type - see {@link FullFeatureCompilationExclusionCliEnhancer}
    • + *
    + */ + @ProcessorTest(baseDir = "fullFeatureTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC, + ProcessorTest.ProcessorType.ECLIPSE_JDT + }, commandLineEnhancer = FullFeatureCompilationExclusionCliEnhancer.class) + void fullFeatureTest() { + } + + @ProcessorTest(baseDir = "immutablesBuilderTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC, + ProcessorTest.ProcessorType.ECLIPSE_JDT + }) + void immutablesBuilderTest() { + } + + @ProcessorTest(baseDir = "java8Test") + void java8Test() { + } + + @ProcessorTest(baseDir = "jaxbTest") + void jaxbTest() { + } + + @ProcessorTest(baseDir = "jakartaJaxbTest") + void jakartaJaxbTest() { + } + + @ProcessorTest(baseDir = "jsr330Test") + @EnabledForJreRange(min = JRE.JAVA_17) + void jsr330Test() { + } + + @ProcessorTest(baseDir = "lombokBuilderTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + @DisabledOnJre(versions = { 27, 28 }) + void lombokBuilderTest() { + } + + @ProcessorTest(baseDir = "lombokModuleTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC, + ProcessorTest.ProcessorType.JAVAC_WITH_PATHS + }) + @EnabledForJreRange(min = JRE.JAVA_11) + @DisabledOnJre(versions = { 27, 28 }) + void lombokModuleTest() { + } + + @ProcessorTest(baseDir = "namingStrategyTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + void namingStrategyTest() { + } + + /** + * ECLIPSE_JDT is not working with Protobuf. Use all other available processor types. + */ + @ProcessorTest(baseDir = "protobufBuilderTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + void protobufBuilderTest() { + } + + @ProcessorTest(baseDir = "sealedSubclassTest") + @EnabledForJreRange(min = JRE.JAVA_17) + void sealedSubclassTest() { + } + + @ProcessorTest(baseDir = "recordsTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + @EnabledForJreRange(min = JRE.JAVA_14) + void recordsTest() { + } + + @ProcessorTest(baseDir = "recordsCrossModuleTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + @EnabledForJreRange(min = JRE.JAVA_17) + void recordsCrossModuleTest() { + } + + @ProcessorTest(baseDir = "recordsCrossModuleInterfaceTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + @EnabledForJreRange(min = JRE.JAVA_17) + void recordsCrossModuleInterfaceTest() { + } + + @ProcessorTest(baseDir = "expressionTextBlocksTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + @EnabledForJreRange(min = JRE.JAVA_17) + void expressionTextBlocksTest() { + } + + @ProcessorTest(baseDir = "kotlinDataTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }, forkJvm = true) + // We have to fork the jvm because there is an NPE in com.intellij.openapi.util.SystemInfo.getRtVersion + // and the kotlin-maven-plugin uses that. See also https://youtrack.jetbrains.com/issue/IDEA-238907 + @DisabledOnJre(versions = 27) + void kotlinDataTest() { + } + + @ProcessorTest(baseDir = "kotlinFullFeatureTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC_WITH_PATHS + }, commandLineEnhancer = KotlinFullFeatureCompilationExclusionCliEnhancer.class) + @DisabledForJreRange(min = JRE.JAVA_26) + void kotlinFullFeatureTest() { + } + + @ProcessorTest(baseDir = "simpleTest") + void simpleTest() { + } + + // for issue #2593 + @ProcessorTest(baseDir = "defaultPackage") + void defaultPackageTest() { + } + + @ProcessorTest(baseDir = "springTest") + @EnabledForJreRange(min = JRE.JAVA_17) + void springTest() { + } + + /** + * Tests usage of MapStruct with another processor that generates supertypes of mapping source/target types. + */ + @ProcessorTest(baseDir = "superTypeGenerationTest", processorTypes = ProcessorTest.ProcessorType.JAVAC) + void superTypeGenerationTest() { + } + + /** + * Tests usage of MapStruct with another processor that generates the target type of a mapping method. + */ + @ProcessorTest(baseDir = "targetTypeGenerationTest", processorTypes = ProcessorTest.ProcessorType.JAVAC) + void targetTypeGenerationTest() { + } + + @ProcessorTest(baseDir = "moduleInfoTest") + @EnabledForJreRange(min = JRE.JAVA_11) + void moduleInfoTest() { + + } + + /** + * Tests usage of MapStruct with another processor that generates the uses type of a mapper. + */ + @ProcessorTest(baseDir = "usesTypeGenerationTest", processorTypes = { + ProcessorTest.ProcessorType.JAVAC + }) + void usesTypeGenerationTest() { + } + + /** + * Tests usage of MapStruct with another processor that generates the uses type of a mapper. + */ + @ProcessorTest(baseDir = "usesTypeGenerationTest", processorTypes = { + ProcessorTest.ProcessorType.ECLIPSE_JDT + }) + @EnabledForJreRange(min = JRE.JAVA_11) + // For some reason the second run with eclipse does not load the ModelElementProcessor(s) on java 8, + // therefore we run this only on Java 11 + void usesTypeGenerationTestEclipse() { + } + + /** + * Tests usage of MapStruct with faulty provider of AstModifyingAnnotationProcessor. + */ + @ProcessorTest(baseDir = "faultyAstModifyingAnnotationProcessorTest") + void faultyAstModifyingProcessor() { + } + +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/NamingStrategyTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/NamingStrategyTest.java deleted file mode 100644 index 39690d5b01..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/NamingStrategyTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite(baseDir = "namingStrategyTest", processorTypes = ProcessorType.ORACLE_JAVA_8) -public class NamingStrategyTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/SimpleTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/SimpleTest.java deleted file mode 100644 index 46389767f8..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/SimpleTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "simpleTest", processorTypes = ProcessorType.ALL ) -public class SimpleTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/SpringTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/SpringTest.java deleted file mode 100644 index eccbceac4e..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/SpringTest.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * @author Andreas Gudian - * - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite( baseDir = "springTest", processorTypes = ProcessorType.ALL ) -public class SpringTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/SuperTypeGenerationTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/SuperTypeGenerationTest.java deleted file mode 100644 index 264f7e4fb0..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/SuperTypeGenerationTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * Tests usage of MapStruct with another processor that generates supertypes of mapping source/target types. - * - * @author Gunnar Morling - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite(baseDir = "superTypeGenerationTest", processorTypes = ProcessorType.ORACLE_JAVA_8) -public class SuperTypeGenerationTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java b/integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java deleted file mode 100644 index 04b9155c52..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/tests/TargetTypeGenerationTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.tests; - -import org.junit.runner.RunWith; -import org.mapstruct.itest.testutil.runner.ProcessorSuite; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner; - -/** - * Tests usage of MapStruct with another processor that generates the target type of a mapping method. - * - * @author Gunnar Morling - */ -@RunWith( ProcessorSuiteRunner.class ) -@ProcessorSuite(baseDir = "targetTypeGenerationTest", processorTypes = ProcessorType.ORACLE_JAVA_8) -public class TargetTypeGenerationTest { -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorEnabledOnJreCondition.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorEnabledOnJreCondition.java new file mode 100644 index 0000000000..a651e55f93 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorEnabledOnJreCondition.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.testutil.extension; + +import org.junit.jupiter.api.extension.ConditionEvaluationResult; +import org.junit.jupiter.api.extension.ExecutionCondition; +import org.junit.jupiter.api.extension.ExtensionContext; + +import static org.mapstruct.itest.testutil.extension.ProcessorTestTemplateInvocationContext.CURRENT_VERSION; + +/** + * @author Filip Hrisafov + */ +public class ProcessorEnabledOnJreCondition implements ExecutionCondition { + + static final ConditionEvaluationResult ENABLED_ON_CURRENT_JRE = + ConditionEvaluationResult.enabled( "Enabled on JRE version: " + System.getProperty( "java.version" ) ); + + static final ConditionEvaluationResult DISABLED_ON_CURRENT_JRE = + ConditionEvaluationResult.disabled( "Disabled on JRE version: " + System.getProperty( "java.version" ) ); + + public ProcessorEnabledOnJreCondition(ProcessorTest.ProcessorType processorType) { + this.processorType = processorType; + } + + protected final ProcessorTest.ProcessorType processorType; + + @Override + public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) { + // If the max JRE is greater or equal to the current version the test is enabled + return processorType.maxJre().compareTo( CURRENT_VERSION ) >= 0 ? ENABLED_ON_CURRENT_JRE : + DISABLED_ON_CURRENT_JRE; + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorInvocationInterceptor.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorInvocationInterceptor.java new file mode 100644 index 0000000000..39cd5fdae6 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorInvocationInterceptor.java @@ -0,0 +1,218 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.testutil.extension; + +import java.io.File; +import java.io.IOException; +import java.io.PrintStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.maven.it.Verifier; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.InvocationInterceptor; +import org.junit.jupiter.api.extension.ReflectiveInvocationContext; +import org.junit.platform.commons.util.ReflectionUtils; + +import static org.apache.maven.it.util.ResourceExtractor.extractResourceToDestination; +import static org.apache.maven.shared.utils.io.FileUtils.copyURLToFile; +import static org.apache.maven.shared.utils.io.FileUtils.deleteDirectory; +import static org.mapstruct.itest.testutil.extension.ProcessorTestTemplateInvocationContext.CURRENT_VERSION; + +/** + * @author Filip Hrisafov + * @author Andreas Gudian + */ +public class ProcessorInvocationInterceptor implements InvocationInterceptor { + + /** + * System property to enable remote debugging of the processor execution in the integration test + */ + public static final String SYS_PROP_DEBUG = "processorIntegrationTest.debug"; + + private final ProcessorTestContext processorTestContext; + + public ProcessorInvocationInterceptor(ProcessorTestContext processorTestContext) { + this.processorTestContext = processorTestContext; + } + + @Override + public void interceptTestTemplateMethod(Invocation invocation, + ReflectiveInvocationContext invocationContext, ExtensionContext extensionContext) throws Throwable { + try { + doExecute( extensionContext ); + invocation.proceed(); + } + catch ( Exception e ) { + invocation.skip(); + throw e; + } + } + + private void doExecute(ExtensionContext extensionContext) throws Exception { + File destination = extractTest( extensionContext ); + PrintStream originalOut = System.out; + + final Verifier verifier; + if ( Boolean.getBoolean( SYS_PROP_DEBUG ) ) { + // the compiler is executed within the Maven JVM. So make + // sure we fork a new JVM for that, and let that new JVM use the command 'mvnDebug' instead of 'mvn' + verifier = new Verifier( destination.getCanonicalPath(), null, true, true ); + verifier.setDebugJvm( true ); + } + else { + verifier = new Verifier( destination.getCanonicalPath() ); + if ( processorTestContext.isForkJvm() ) { + verifier.setForkJvm( true ); + } + } + + List goals = new ArrayList<>( 3 ); + + goals.add( "clean" ); + + try { + configureProcessor( verifier ); + + verifier.addCliOption( "-Dcompiler-source-target-version=" + sourceTargetVersion() ); + + if ( Boolean.getBoolean( SYS_PROP_DEBUG ) ) { + originalOut.print( "Processor Integration Test: " ); + originalOut.println( "Listening for transport dt_socket at address: 8000 (in some seconds)" ); + } + + goals.add( "test" ); + + addAdditionalCliArguments( verifier ); + + originalOut.println( extensionContext.getRequiredTestClass().getSimpleName() + "." + + extensionContext.getRequiredTestMethod().getName() + " executing " + + processorTestContext.getProcessor().name().toLowerCase() ); + + verifier.executeGoals( goals ); + verifier.verifyErrorFreeLog(); + } + finally { + verifier.resetStreams(); + } + } + + private void addAdditionalCliArguments(Verifier verifier) + throws Exception { + Class cliEnhancerClass = + processorTestContext.getCliEnhancerClass(); + + Constructor cliEnhancerConstructor = null; + if ( cliEnhancerClass != ProcessorTest.CommandLineEnhancer.class ) { + try { + cliEnhancerConstructor = cliEnhancerClass.getConstructor(); + ProcessorTest.CommandLineEnhancer enhancer = cliEnhancerConstructor.newInstance(); + Collection additionalArgs = enhancer.getAdditionalCommandLineArguments( + processorTestContext.getProcessor(), CURRENT_VERSION ); + + for ( String arg : additionalArgs ) { + verifier.addCliOption( arg ); + } + + } + catch ( NoSuchMethodException e ) { + throw new RuntimeException( cliEnhancerClass + " does not have a default constructor." ); + } + catch ( SecurityException e ) { + throw new RuntimeException( e ); + } + } + } + + private void configureProcessor(Verifier verifier) { + ProcessorTest.ProcessorType processor = processorTestContext.getProcessor(); + String compilerId = processor.getCompilerId(); + String profile = processor.getProfile(); + if ( profile == null ) { + profile = "generate-via-compiler-plugin"; + } + verifier.addCliOption( "-P" + profile ); + verifier.addCliOption( "-Dcompiler-id=" + compilerId ); + if ( processor == ProcessorTest.ProcessorType.JAVAC ) { + if ( CURRENT_VERSION.ordinal() >= JRE.JAVA_21.ordinal() ) { + verifier.addCliOption( "-Dmaven.compiler.proc=full" ); + } + } + } + + private File extractTest(ExtensionContext extensionContext) throws IOException { + String tmpDir = getTmpDir(); + + String tempDirName = extensionContext.getRequiredTestClass().getPackage().getName() + "." + + extensionContext.getRequiredTestMethod().getName(); + File tempDirBase = new File( tmpDir, tempDirName ).getCanonicalFile(); + + if ( !tempDirBase.exists() ) { + tempDirBase.mkdirs(); + } + + File parentPom = new File( tempDirBase, "pom.xml" ); + copyURLToFile( getClass().getResource( "/pom.xml" ), parentPom ); + + ProcessorTest.ProcessorType processorType = processorTestContext.getProcessor(); + File tempDir = new File( tempDirBase, processorType.name().toLowerCase() ); + deleteDirectory( tempDir ); + + return extractResourceToDestination( getClass(), "/" + processorTestContext.getBaseDir(), tempDir, true ); + } + + private String getTmpDir() { + if ( CURRENT_VERSION == JRE.JAVA_8 ) { + // On Java 8 the tmp dir is always + // no matter we run from the aggregator or not + return "target/tmp"; + } + + // On Java 11+ we need to do it base on the location relative + String tmpDir; + if ( Files.exists( Paths.get( "integrationtest" ) ) ) { + // If it exists then we are running from the main aggregator + tmpDir = "integrationtest/target/tmp"; + } + else { + tmpDir = "target/tmp"; + } + return tmpDir; + } + + private String sourceTargetVersion() { + if ( CURRENT_VERSION == JRE.JAVA_8 ) { + return "1.8"; + } + else if ( CURRENT_VERSION == JRE.OTHER ) { + try { + // Extracting the major version is done with code from + // org.junit.jupiter.api.condition.JRE when determining the current version + + // java.lang.Runtime.version() is a static method available on Java 9+ + // that returns an instance of java.lang.Runtime.Version which has the + // following method: public int major() + Method versionMethod = null; + versionMethod = Runtime.class.getMethod( "version" ); + Object version = ReflectionUtils.invokeMethod( versionMethod, null ); + Method majorMethod = version.getClass().getMethod( "major" ); + return String.valueOf( (int) ReflectionUtils.invokeMethod( majorMethod, version ) ); + } + catch ( NoSuchMethodException e ) { + throw new RuntimeException( "Failed to get Java Version" ); + } + } + else { + return CURRENT_VERSION.name().substring( 5 ); + } + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTest.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTest.java new file mode 100644 index 0000000000..d5b4860d5b --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTest.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.testutil.extension; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Collection; + +import org.apache.maven.it.Verifier; +import org.junit.jupiter.api.TestTemplate; +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.extension.ExtendWith; + +/** + * Declares the content of the integration test. + *

    + * {@link #baseDir()} must be a path in the classpath that contains the maven module to run as integration test. The + * integration test module should contain at least one test class. The integration test passes, if + * {@code mvn clean test} finishes successfully. + *

    + * {@link #processorTypes()} configures the variants to execute the integration tests with. See + * {@link ProcessorType}. + * + * @author Filip Hrisafov + */ +@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD }) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@TestTemplate +@ExtendWith(ProcessorTestTemplateInvocationContextProvider.class) +public @interface ProcessorTest { + + /** + * Describes the type of the processing variant(s) to use when executing the integration test. + * + * @author Filip Hrisafov + */ + enum ProcessorType { + + JAVAC( "javac" ), + JAVAC_WITH_PATHS( "javac", JRE.OTHER, "generate-via-compiler-plugin-with-annotation-processor-paths" ), + + ECLIPSE_JDT( "jdt", JRE.JAVA_8 ); + + private final String compilerId; + private final JRE max; + private final String profile; + + ProcessorType(String compilerId) { + this( compilerId, JRE.OTHER ); + } + + ProcessorType(String compilerId, JRE max) { + this( compilerId, max, null ); + } + + ProcessorType(String compilerId, JRE max, String profile) { + this.compilerId = compilerId; + this.max = max; + this.profile = profile; + } + + public String getCompilerId() { + return compilerId; + } + + public JRE maxJre() { + return max; + } + + public String getProfile() { + return profile; + } + } + + /** + * Can be configured to provide additional command line arguments for the invoked Maven process, depending on the + * {@link ProcessorType} the test is executed for. + * + * @author Andreas Gudian + */ + interface CommandLineEnhancer { + /** + * @param processorType the processor type for which the test is executed. + * @param currentJreVersion the current JRE version + * + * @return additional command line arguments to be passed to the Maven {@link Verifier}. + */ + Collection getAdditionalCommandLineArguments(ProcessorType processorType, + JRE currentJreVersion); + } + + + /** + * @return a path in the classpath that contains the maven module to run as integration test: {@code mvn clean test} + */ + String baseDir(); + + /** + * @return the variants to execute the integration tests with. See {@link ProcessorType}. + */ + ProcessorType[] processorTypes() default { + ProcessorType.JAVAC, + ProcessorType.JAVAC_WITH_PATHS, + ProcessorType.ECLIPSE_JDT, + }; + + /** + * @return the {@link CommandLineEnhancer} implementation. Must have a default constructor. + */ + Class commandLineEnhancer() default CommandLineEnhancer.class; + + boolean forkJvm() default false; + +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestContext.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestContext.java new file mode 100644 index 0000000000..feb5c7dc02 --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestContext.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.testutil.extension; + +/** + * @author Filip Hrisafov + */ +public class ProcessorTestContext { + + private final String baseDir; + private final ProcessorTest.ProcessorType processor; + private final Class cliEnhancerClass; + private final boolean forkJvm; + + public ProcessorTestContext(String baseDir, + ProcessorTest.ProcessorType processor, + Class cliEnhancerClass, + boolean forkJvm) { + this.baseDir = baseDir; + this.processor = processor; + this.cliEnhancerClass = cliEnhancerClass; + this.forkJvm = forkJvm; + } + + public String getBaseDir() { + return baseDir; + } + + public ProcessorTest.ProcessorType getProcessor() { + return processor; + } + + public Class getCliEnhancerClass() { + return cliEnhancerClass; + } + + public boolean isForkJvm() { + return forkJvm; + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestTemplateInvocationContext.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestTemplateInvocationContext.java new file mode 100644 index 0000000000..47e692988d --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestTemplateInvocationContext.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.testutil.extension; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.condition.JRE; +import org.junit.jupiter.api.extension.Extension; +import org.junit.jupiter.api.extension.TestTemplateInvocationContext; + +/** + * @author Filip Hrisafov + */ +public class ProcessorTestTemplateInvocationContext implements TestTemplateInvocationContext { + + static final JRE CURRENT_VERSION; + + static { + JRE currentVersion = JRE.OTHER; + for ( JRE jre : JRE.values() ) { + if ( jre.isCurrentVersion() ) { + currentVersion = jre; + break; + } + } + + CURRENT_VERSION = currentVersion; + } + + private final ProcessorTestContext processorTestContext; + + public ProcessorTestTemplateInvocationContext(ProcessorTestContext processorTestContext) { + this.processorTestContext = processorTestContext; + } + + @Override + public String getDisplayName(int invocationIndex) { + return processorTestContext.getProcessor().name().toLowerCase(); + } + + @Override + public List getAdditionalExtensions() { + List extensions = new ArrayList<>(); + extensions.add( new ProcessorEnabledOnJreCondition( processorTestContext.getProcessor() ) ); + extensions.add( new ProcessorInvocationInterceptor( processorTestContext ) ); + return extensions; + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestTemplateInvocationContextProvider.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestTemplateInvocationContextProvider.java new file mode 100644 index 0000000000..5ceb44804d --- /dev/null +++ b/integrationtest/src/test/java/org/mapstruct/itest/testutil/extension/ProcessorTestTemplateInvocationContextProvider.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.testutil.extension; + +import java.lang.reflect.Method; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.TestTemplateInvocationContext; +import org.junit.jupiter.api.extension.TestTemplateInvocationContextProvider; +import org.junit.platform.commons.support.AnnotationSupport; + +/** + * @author Filip Hrisafov + */ +public class ProcessorTestTemplateInvocationContextProvider implements TestTemplateInvocationContextProvider { + @Override + public boolean supportsTestTemplate(ExtensionContext context) { + return AnnotationSupport.isAnnotated( context.getTestMethod(), ProcessorTest.class ); + } + + @Override + public Stream provideTestTemplateInvocationContexts(ExtensionContext context) { + + Method testMethod = context.getRequiredTestMethod(); + ProcessorTest processorTest = AnnotationSupport.findAnnotation( testMethod, ProcessorTest.class ) + .orElseThrow( () -> new RuntimeException( "Failed to get ProcessorTest on " + testMethod ) ); + + + return Stream.of( processorTest.processorTypes() ) + .map( processorType -> new ProcessorTestTemplateInvocationContext( new ProcessorTestContext( + processorTest.baseDir(), + processorType, + processorTest.commandLineEnhancer(), + processorTest.forkJvm() + ) ) ); + } +} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java deleted file mode 100644 index 62ad61f936..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuite.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.testutil.runner; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import java.util.Collection; - -import org.apache.maven.it.Verifier; - -/** - * Declares the content of the integration test. - *

    - * {@link #baseDir()} must be a path in the classpath that contains the maven module to run as integration test. The - * integration test module should contain at least one test class. The integration test passes, if - * {@code mvn clean test} finishes successfully. - *

    - * {@link #processorTypes()} configures the variants to execute the integration tests with. See {@link ProcessorType}. - * - * @author Andreas Gudian - */ -@Retention( RetentionPolicy.RUNTIME ) -@Documented -@Target( ElementType.TYPE ) -public @interface ProcessorSuite { - /** - * Describes the type of the processing variant(s) to use when executing the integration test. - *

    - * Types that require toolchains, will - * need the toolchains.xml file to be either installed in ~/m2, or alternatively passed to the mvn process using - * {@code mvn -DprocessorIntegrationTest.toolchainsFile=/path/to/toolchains.xml ...} - * - * @author Andreas Gudian - */ - enum ProcessorType { - /** - * Use an Oracle JDK 1.6 (or 1.6.x) via toolchain support to perform the processing - */ - ORACLE_JAVA_6( new Toolchain( "oracle", "1.6", "1.7" ), "javac", "1.6" ), - - /** - * Use an Oracle JDK 1.7 (or 1.7.x) via toolchain support to perform the processing - */ - ORACLE_JAVA_7( new Toolchain( "oracle", "1.7", "1.8" ), "javac", "1.7" ), - - /** - * Use the same JDK that runs the mvn build to perform the processing - */ - ORACLE_JAVA_8( null, "javac", "1.8" ), - - /** - * Use an Oracle JDK 1.9 (or 1.9.x) via toolchain support to perform the processing - */ - ORACLE_JAVA_9( new Toolchain( "oracle", "9", "10" ), "javac", "1.9" ), - - /** - * Use the eclipse compiler with 1.6 source/target level from tycho-compiler-jdt to perform the build and - * processing - */ - ECLIPSE_JDT_JAVA_6( null, "jdt", "1.6" ), - - /** - * Use the eclipse compiler with 1.7 source/target level from tycho-compiler-jdt to perform the build and - * processing - */ - ECLIPSE_JDT_JAVA_7( null, "jdt", "1.7" ), - - /** - * Use the eclipse compiler with 1.8 source/target level from tycho-compiler-jdt to perform the build and - * processing - */ - ECLIPSE_JDT_JAVA_8( null, "jdt", "1.8" ), - - /** - * Use the maven-processor-plugin with 1.8 source/target level with the same JDK that runs the mvn build to - * perform the processing - */ - PROCESSOR_PLUGIN_JAVA_8( null, null, "1.8" ), - - /** - * Use all processing variants, but without the maven-procesor-plugin - */ - ALL_WITHOUT_PROCESSOR_PLUGIN(ORACLE_JAVA_6, ORACLE_JAVA_7, ORACLE_JAVA_8, ORACLE_JAVA_9, ECLIPSE_JDT_JAVA_6, - ECLIPSE_JDT_JAVA_7, ECLIPSE_JDT_JAVA_8), - - /** - * Use all available processing variants - */ - ALL( ORACLE_JAVA_6, ORACLE_JAVA_7, ORACLE_JAVA_8, ORACLE_JAVA_9, ECLIPSE_JDT_JAVA_6, ECLIPSE_JDT_JAVA_7, - ECLIPSE_JDT_JAVA_8, PROCESSOR_PLUGIN_JAVA_8 ), - - /** - * Use all JDK8 compatible processing variants - */ - ALL_JAVA_8( ORACLE_JAVA_8, ECLIPSE_JDT_JAVA_8, PROCESSOR_PLUGIN_JAVA_8 ); - - private ProcessorType[] included = { }; - - private Toolchain toolchain; - private String compilerId; - private String sourceTargetVersion; - - ProcessorType(Toolchain toolchain, String compilerId, String sourceTargetVersion) { - this.toolchain = toolchain; - this.compilerId = compilerId; - this.sourceTargetVersion = sourceTargetVersion; - } - - ProcessorType(ProcessorType... included) { - this.included = included; - } - - /** - * @return the processor types that are grouped by this type - */ - public ProcessorType[] getIncluded() { - return included; - } - - /** - * @return the toolchain - */ - public Toolchain getToolchain() { - return toolchain; - } - - /** - * @return the compilerId - */ - public String getCompilerId() { - return compilerId; - } - - /** - * @return the sourceTargetVersion - */ - public String getSourceTargetVersion() { - return sourceTargetVersion; - } - } - - /** - * Can be configured to provide additional command line arguments for the invoked Maven process, depending on the - * {@link ProcessorType} the test is executed for. - * - * @author Andreas Gudian - */ - interface CommandLineEnhancer { - /** - * @param processorType the processor type for which the test is executed. - * @return additional command line arguments to be passed to the Maven {@link Verifier}. - */ - Collection getAdditionalCommandLineArguments(ProcessorType processorType); - } - - /** - * @return a path in the classpath that contains the maven module to run as integration test: {@code mvn clean test} - */ - String baseDir(); - - /** - * @return the variants to execute the integration tests with. See {@link ProcessorType}. - */ - ProcessorType[] processorTypes() default { ProcessorType.ALL }; - - /** - * @return the {@link CommandLineEnhancer} implementation. Must have a default constructor. - */ - Class commandLineEnhancer() default CommandLineEnhancer.class; -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java deleted file mode 100644 index 4e287b8005..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/ProcessorSuiteRunner.java +++ /dev/null @@ -1,373 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.testutil.runner; - -import static org.apache.maven.it.util.ResourceExtractor.extractResourceToDestination; -import static org.apache.maven.shared.utils.io.FileUtils.copyURLToFile; -import static org.apache.maven.shared.utils.io.FileUtils.deleteDirectory; - -import java.io.File; -import java.io.IOException; -import java.io.PrintStream; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import org.apache.maven.it.Verifier; -import org.junit.internal.AssumptionViolatedException; -import org.junit.internal.runners.model.EachTestNotifier; -import org.junit.runner.Description; -import org.junit.runner.notification.RunNotifier; -import org.junit.runner.notification.StoppedByUserException; -import org.junit.runners.ParentRunner; -import org.junit.runners.model.InitializationError; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.CommandLineEnhancer; -import org.mapstruct.itest.testutil.runner.ProcessorSuite.ProcessorType; -import org.mapstruct.itest.testutil.runner.ProcessorSuiteRunner.ProcessorTestCase; -import org.mapstruct.itest.testutil.runner.xml.Toolchains; -import org.mapstruct.itest.testutil.runner.xml.Toolchains.ProviderDescription; - -/** - * Runner for processor integration tests. Requires the annotation {@link ProcessorSuite} on the test class. - * - * @author Andreas Gudian - */ -public class ProcessorSuiteRunner extends ParentRunner { - - /** - * System property for specifying the location of the toolchains.xml file - */ - public static final String SYS_PROP_TOOLCHAINS_FILE = "processorIntegrationTest.toolchainsFile"; - - /** - * System property to enable remote debugging of the processor execution in the integration test - */ - public static final String SYS_PROP_DEBUG = "processorIntegrationTest.debug"; - - private static final File TOOLCHAINS_FILE = getToolchainsFile(); - - private static final Collection ENABLED_PROCESSOR_TYPES = detectSupportedTypes( TOOLCHAINS_FILE ); - - public static final class ProcessorTestCase { - private final String baseDir; - private final ProcessorType processor; - private final boolean ignored; - private final Constructor cliEnhancerConstructor; - - public ProcessorTestCase(String baseDir, ProcessorType processor, - Constructor cliEnhancerConstructor) { - this.baseDir = baseDir; - this.processor = processor; - this.cliEnhancerConstructor = cliEnhancerConstructor; - this.ignored = !ENABLED_PROCESSOR_TYPES.contains( processor ); - } - } - - private final List methods; - - /** - * @param clazz the test class - * @throws InitializationError in case the initialization fails - */ - public ProcessorSuiteRunner(Class clazz) throws InitializationError { - super( clazz ); - - ProcessorSuite suite = clazz.getAnnotation( ProcessorSuite.class ); - - if ( null == suite ) { - throw new InitializationError( "The test class must be annotated with " + ProcessorSuite.class.getName() ); - } - - if ( suite.processorTypes().length == 0 ) { - throw new InitializationError( "ProcessorSuite#processorTypes must not be empty" ); - } - - Constructor cliEnhancerConstructor = null; - if ( suite.commandLineEnhancer() != CommandLineEnhancer.class ) { - try { - cliEnhancerConstructor = suite.commandLineEnhancer().getConstructor(); - } - catch ( NoSuchMethodException e ) { - throw new InitializationError( - suite.commandLineEnhancer().getName() + " does not have a default constructor." ); - } - catch ( SecurityException e ) { - throw new InitializationError( e ); - } - } - - methods = initializeTestCases( suite, cliEnhancerConstructor ); - } - - private List initializeTestCases(ProcessorSuite suite, - Constructor cliEnhancerConstructor) { - List types = new ArrayList(); - - for ( ProcessorType compiler : suite.processorTypes() ) { - if ( compiler.getIncluded().length > 0 ) { - types.addAll( Arrays.asList( compiler.getIncluded() ) ); - } - else { - types.add( compiler ); - } - } - - List result = new ArrayList( types.size() ); - - for ( ProcessorType type : types ) { - result.add( new ProcessorTestCase( suite.baseDir(), type, cliEnhancerConstructor ) ); - } - - return result; - } - - @Override - protected List getChildren() { - return methods; - } - - @Override - protected Description describeChild(ProcessorTestCase child) { - return Description.createTestDescription( getTestClass().getJavaClass(), child.processor.name().toLowerCase() ); - } - - @Override - protected void runChild(ProcessorTestCase child, RunNotifier notifier) { - Description description = describeChild( child ); - EachTestNotifier testNotifier = new EachTestNotifier( notifier, description ); - - if ( child.ignored ) { - testNotifier.fireTestIgnored(); - } - else { - try { - testNotifier.fireTestStarted(); - doExecute( child, description ); - } - catch ( AssumptionViolatedException e ) { - testNotifier.fireTestIgnored(); - } - catch ( StoppedByUserException e ) { - throw e; - } - catch ( Throwable e ) { - testNotifier.addFailure( e ); - } - finally { - testNotifier.fireTestFinished(); - } - } - } - - private void doExecute(ProcessorTestCase child, Description description) throws Exception { - File destination = extractTest( child, description ); - PrintStream originalOut = System.out; - - final Verifier verifier; - if ( Boolean.getBoolean( SYS_PROP_DEBUG ) ) { - if ( child.processor.getToolchain() == null ) { - // when not using toolchains for a test, then the compiler is executed within the Maven JVM. So make - // sure we fork a new JVM for that, and let that new JVM use the command 'mvnDebug' instead of 'mvn' - verifier = new Verifier( destination.getCanonicalPath(), null, true, true ); - verifier.setDebugJvm( true ); - } - else { - verifier = new Verifier( destination.getCanonicalPath() ); - verifier.addCliOption( "-Pdebug-forked-javac" ); - } - } - else { - verifier = new Verifier( destination.getCanonicalPath() ); - } - - List goals = new ArrayList( 3 ); - - goals.add( "clean" ); - - try { - configureToolchains( child, verifier, goals, originalOut ); - configureProcessor( child, verifier ); - - verifier.addCliOption( "-Dcompiler-source-target-version=" + child.processor.getSourceTargetVersion() ); - - if ( "1.8".equals( child.processor.getSourceTargetVersion() ) - || "1.9".equals( child.processor.getSourceTargetVersion() ) ) { - verifier.addCliOption( "-Dmapstruct-artifact-id=mapstruct-jdk8" ); - } - else { - verifier.addCliOption( "-Dmapstruct-artifact-id=mapstruct" ); - } - - if ( Boolean.getBoolean( SYS_PROP_DEBUG ) ) { - originalOut.print( "Processor Integration Test: " ); - originalOut.println( "Listening for transport dt_socket at address: 8000 (in some seconds)" ); - } - - goals.add( "test" ); - - addAdditionalCliArguments( child, verifier ); - - originalOut.println( "executing " + child.processor.name().toLowerCase() ); - - verifier.executeGoals( goals ); - verifier.verifyErrorFreeLog(); - } - finally { - verifier.resetStreams(); - } - } - - private void addAdditionalCliArguments(ProcessorTestCase child, final Verifier verifier) throws Exception { - if ( child.cliEnhancerConstructor != null ) { - CommandLineEnhancer enhancer = child.cliEnhancerConstructor.newInstance(); - Collection additionalArgs = enhancer.getAdditionalCommandLineArguments( child.processor ); - - if ( additionalArgs != null ) { - for ( String arg : additionalArgs ) { - verifier.addCliOption( arg ); - } - } - } - } - - private void configureProcessor(ProcessorTestCase child, Verifier verifier) { - if ( child.processor.getCompilerId() != null ) { - verifier.addCliOption( "-Pgenerate-via-compiler-plugin" ); - verifier.addCliOption( "-Dcompiler-id=" + child.processor.getCompilerId() ); - } - else { - verifier.addCliOption( "-Pgenerate-via-processor-plugin" ); - } - } - - private void configureToolchains(ProcessorTestCase child, Verifier verifier, List goals, - PrintStream originalOut) { - if ( child.processor.getToolchain() != null ) { - verifier.addCliOption( "--toolchains" ); - verifier.addCliOption( TOOLCHAINS_FILE.getPath().replace( '\\', '/' ) ); - - Toolchain toolchain = child.processor.getToolchain(); - - verifier.addCliOption( "-Dtoolchain-jdk-vendor=" + toolchain.getVendor() ); - verifier.addCliOption( "-Dtoolchain-jdk-version=" + toolchain.getVersionRangeString() ); - - goals.add( "toolchains:toolchain" ); - } - } - - private File extractTest(ProcessorTestCase child, Description description) throws IOException { - File tempDirBase = new File( "target/tmp", description.getClassName() ).getCanonicalFile(); - - if ( !tempDirBase.exists() ) { - tempDirBase.mkdirs(); - } - - File parentPom = new File( tempDirBase, "pom.xml" ); - copyURLToFile( getClass().getResource( "/pom.xml" ), parentPom ); - - File tempDir = new File( tempDirBase, description.getMethodName() ); - deleteDirectory( tempDir ); - - return extractResourceToDestination( getClass(), "/" + child.baseDir, tempDir, true ); - } - - private static File getToolchainsFile() { - String specifiedToolchainsFile = System.getProperty( SYS_PROP_TOOLCHAINS_FILE ); - if ( null != specifiedToolchainsFile ) { - try { - File canonical = new File( specifiedToolchainsFile ).getCanonicalFile(); - if ( canonical.exists() ) { - return canonical; - } - - // check the path relative to the parent directory (allows specifying a path relative to the top-level - // aggregator module) - canonical = new File( "..", specifiedToolchainsFile ).getCanonicalFile(); - if ( canonical.exists() ) { - return canonical; - } - } - catch ( IOException e ) { - return null; - } - } - - // use default location - String defaultPath = System.getProperty( "user.home" ) + System.getProperty( "file.separator" ) + ".m2"; - return new File( defaultPath, "toolchains.xml" ); - } - - private static Collection detectSupportedTypes(File toolchainsFile) { - Toolchains toolchains; - try { - if ( toolchainsFile.exists() ) { - Unmarshaller unmarshaller = JAXBContext.newInstance( Toolchains.class ).createUnmarshaller(); - toolchains = (Toolchains) unmarshaller.unmarshal( toolchainsFile ); - } - else { - toolchains = null; - } - } - catch ( JAXBException e ) { - toolchains = null; - } - - Collection supported = new HashSet<>(); - for ( ProcessorType type : ProcessorType.values() ) { - if ( isSupported( type, toolchains ) ) { - supported.add( type ); - } - } - - return supported; - } - - private static boolean isSupported(ProcessorType type, Toolchains toolchains) { - if ( type.getToolchain() == null ) { - return true; - } - - if ( toolchains == null ) { - return false; - } - - Toolchain required = type.getToolchain(); - - for ( Toolchains.Toolchain tc : toolchains.getToolchains() ) { - if ( "jdk".equals( tc.getType() ) ) { - ProviderDescription desc = tc.getProviderDescription(); - if ( desc != null - && required.getVendor().equals( desc.getVendor() ) - && desc.getVersion() != null - && desc.getVersion().startsWith( required.getVersionMinInclusive() ) ) { - return true; - } - } - } - - return false; - } -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java deleted file mode 100644 index 05e6d8e6b9..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/Toolchain.java +++ /dev/null @@ -1,51 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.testutil.runner; - -/** - * Describes a required entry in the Maven toolchains.xml file. - * - * @author Andreas Gudian - */ -class Toolchain { - private final String vendor; - private final String versionMinInclusive; - private final String versionMaxExclusive; - - Toolchain(String vendor, String versionMinInclusive, String versionMaxExclusive) { - this.vendor = vendor; - this.versionMinInclusive = versionMinInclusive; - this.versionMaxExclusive = versionMaxExclusive; - } - - String getVendor() { - return vendor; - } - - String getVersionMinInclusive() { - return versionMinInclusive; - } - - /** - * @return the version range string to be used in the Maven execution to select the toolchain - */ - String getVersionRangeString() { - return "[" + versionMinInclusive + "," + versionMaxExclusive + ")"; - } -} diff --git a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java b/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java deleted file mode 100644 index bee02f692c..0000000000 --- a/integrationtest/src/test/java/org/mapstruct/itest/testutil/runner/xml/Toolchains.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.testutil.runner.xml; - -import java.util.ArrayList; -import java.util.List; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -/** - * JAXB representation of some of the parts in the Maven toolchains.xml file. - * - * @author Andreas Gudian - */ -@XmlRootElement -public class Toolchains { - @XmlElement(name = "toolchain") - private List toolchains = new ArrayList<>(); - - public List getToolchains() { - return toolchains; - } - - @Override - public String toString() { - return "Toolchains [toolchains=" + toolchains + "]"; - } - - public static class Toolchain { - @XmlElement - private String type; - - @XmlElement(name = "provides") - private ProviderDescription providerDescription; - - public String getType() { - return type; - } - - public ProviderDescription getProviderDescription() { - return providerDescription; - } - - @Override - public String toString() { - return "Toolchain [type=" + type + ", providerDescription=" + providerDescription + "]"; - } - } - - public static class ProviderDescription { - @XmlElement - private String version; - - @XmlElement - private String vendor; - - public String getVersion() { - return version; - } - - public String getVendor() { - return vendor; - } - - @Override - public String toString() { - return "ProviderDescription [version=" + version + ", vendor=" + vendor + "]"; - } - } -} diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/pom.xml b/integrationtest/src/test/resources/autoValueBuilderTest/pom.xml index 3d37a1d024..383ab4efbe 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/pom.xml +++ b/integrationtest/src/test/resources/autoValueBuilderTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Address.java b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Address.java index ff0da32ecb..97eb723193 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Address.java +++ b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.auto.value; diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/AddressDto.java b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/AddressDto.java index fe3d6d9ee7..35eed1cb11 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/AddressDto.java +++ b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.auto.value; diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Person.java b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Person.java index af46d576ec..4f71c55c4a 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Person.java +++ b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.auto.value; diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonDto.java b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonDto.java index 13f8d084df..f3e2ecede5 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonDto.java +++ b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.auto.value; diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonMapper.java b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonMapper.java index 2e585c545c..9e916c8ad7 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonMapper.java +++ b/integrationtest/src/test/resources/autoValueBuilderTest/src/main/java/org/mapstruct/itest/auto/value/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.auto.value; diff --git a/integrationtest/src/test/resources/autoValueBuilderTest/src/test/java/org/mapstruct/itest/auto/value/AutoValueMapperTest.java b/integrationtest/src/test/resources/autoValueBuilderTest/src/test/java/org/mapstruct/itest/auto/value/AutoValueMapperTest.java index 93f5d58958..4ce5530a5d 100644 --- a/integrationtest/src/test/resources/autoValueBuilderTest/src/test/java/org/mapstruct/itest/auto/value/AutoValueMapperTest.java +++ b/integrationtest/src/test/resources/autoValueBuilderTest/src/test/java/org/mapstruct/itest/auto/value/AutoValueMapperTest.java @@ -1,24 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.auto.value; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -27,10 +14,10 @@ * * @author Eric Martineau */ -public class AutoValueMapperTest { +class AutoValueMapperTest { @Test - public void testSimpleImmutableBuilderHappyPath() { + void testSimpleImmutableBuilderHappyPath() { PersonDto personDto = PersonMapper.INSTANCE.toDto( Person.builder() .age( 33 ) .name( "Bob" ) @@ -45,7 +32,7 @@ public void testSimpleImmutableBuilderHappyPath() { } @Test - public void testLombokToImmutable() { + void testLombokToImmutable() { Person person = PersonMapper.INSTANCE.fromDto( new PersonDto( "Bob", 33, new AddressDto( "Wild Drive" ) ) ); assertThat( person.getAge() ).isEqualTo( 33 ); assertThat( person.getName() ).isEqualTo( "Bob" ); diff --git a/integrationtest/src/test/resources/cdiTest/pom.xml b/integrationtest/src/test/resources/cdiTest/pom.xml index 0df46e0e11..cb00fbaa01 100644 --- a/integrationtest/src/test/resources/cdiTest/pom.xml +++ b/integrationtest/src/test/resources/cdiTest/pom.xml @@ -1,22 +1,9 @@ @@ -43,8 +30,8 @@ javax.inject - org.jboss.arquillian.junit - arquillian-junit-container + org.jboss.arquillian.junit5 + arquillian-junit5-container test @@ -58,8 +45,8 @@ test - org.jboss.arquillian.junit - arquillian-junit-core + org.jboss.arquillian.junit5 + arquillian-junit5-core test @@ -69,7 +56,7 @@ org.jboss.weld - weld-core + weld-core-impl test diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java index 55b95159b9..23bb51a6c9 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/DecoratedSourceTargetMapper.java @@ -1,28 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi; -import org.mapstruct.Mapper; import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.cdi.other.DateMapper; -@Mapper( componentModel = "cdi", uses = DateMapper.class ) +@Mapper( componentModel = MappingConstants.ComponentModel.CDI, uses = DateMapper.class ) public interface DecoratedSourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Source.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Source.java index 7c0940cded..ea2910015a 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Source.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi; diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java index 0b0c6f92cf..eb895f5e5a 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapper.java @@ -1,27 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.cdi.other.DateMapper; -@Mapper(componentModel = "cdi", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, uses = DateMapper.class) public interface SourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java index 96bc09dc4a..8dd673a2e2 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/SourceTargetMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi; diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Target.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Target.java index 94c1727030..857ab8aaf2 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Target.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi; diff --git a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java index bb09803b84..a9c4706bd8 100644 --- a/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java +++ b/integrationtest/src/test/resources/cdiTest/src/main/java/org/mapstruct/itest/cdi/other/DateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi.other; diff --git a/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java b/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java index b86ab2d040..95d2064938 100644 --- a/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java +++ b/integrationtest/src/test/resources/cdiTest/src/test/java/org/mapstruct/itest/cdi/CdiBasedMapperTest.java @@ -1,43 +1,30 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.cdi; -import static org.assertj.core.api.Assertions.assertThat; - import javax.inject.Inject; import org.jboss.arquillian.container.test.api.Deployment; -import org.jboss.arquillian.junit.Arquillian; +import org.jboss.arquillian.junit5.ArquillianExtension; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.asset.StringAsset; import org.jboss.shrinkwrap.api.spec.JavaArchive; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.itest.cdi.other.DateMapper; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for generation of CDI-based mapper implementations. * * @author Gunnar Morling */ -@RunWith( Arquillian.class ) -public class CdiBasedMapperTest { +@ExtendWith( ArquillianExtension.class ) +class CdiBasedMapperTest { @Inject private SourceTargetMapper mapper; @@ -51,12 +38,14 @@ public static JavaArchive createDeployment() { .addPackage( SourceTargetMapper.class.getPackage() ) .addPackage( DateMapper.class.getPackage() ) .addAsManifestResource( - new StringAsset("org.mapstruct.itest.cdi.SourceTargetMapperDecorator"), + new StringAsset("" + + "org.mapstruct.itest.cdi.SourceTargetMapperDecorator" + + ""), "beans.xml" ); } @Test - public void shouldCreateCdiBasedMapper() { + void shouldCreateCdiBasedMapper() { Source source = new Source(); Target target = mapper.sourceToTarget( source ); @@ -67,7 +56,7 @@ public void shouldCreateCdiBasedMapper() { } @Test - public void shouldInjectDecorator() { + void shouldInjectDecorator() { Source source = new Source(); Target target = decoratedMapper.sourceToTarget( source ); diff --git a/integrationtest/src/test/resources/defaultPackage/main/java/DefaultPackageObject.java b/integrationtest/src/test/resources/defaultPackage/main/java/DefaultPackageObject.java new file mode 100644 index 0000000000..ba684850b4 --- /dev/null +++ b/integrationtest/src/test/resources/defaultPackage/main/java/DefaultPackageObject.java @@ -0,0 +1,97 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +public class DefaultPackageObject { + public enum CarType { + SEDAN, CAMPER, X4, TRUCK; + } + + static public class Car { + + private String make; + private int numberOfSeats; + private CarType type; + + public Car(String string, int numberOfSeats, CarType sedan) { + this.make = string; + this.numberOfSeats = numberOfSeats; + this.type = sedan; + } + + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getNumberOfSeats() { + return numberOfSeats; + } + + public void setNumberOfSeats(int numberOfSeats) { + this.numberOfSeats = numberOfSeats; + } + + public CarType getType() { + return type; + } + + public void setType(CarType type) { + this.type = type; + } + } + + static public class CarDto { + + private String make; + private int seatCount; + private String type; + + public String getMake() { + return make; + } + + public void setMake(String make) { + this.make = make; + } + + public int getSeatCount() { + return seatCount; + } + + public void setSeatCount(int seatCount) { + this.seatCount = seatCount; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } + + + @Mapper + public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + @Mapping(source = "numberOfSeats", target = "seatCount") + CarDto carToCarDto(Car car); + } +} diff --git a/integrationtest/src/test/resources/defaultPackage/pom.xml b/integrationtest/src/test/resources/defaultPackage/pom.xml new file mode 100644 index 0000000000..d72300f618 --- /dev/null +++ b/integrationtest/src/test/resources/defaultPackage/pom.xml @@ -0,0 +1,21 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + defaultPackage + jar + diff --git a/integrationtest/src/test/resources/defaultPackage/test/java/DefaultPackageTest.java b/integrationtest/src/test/resources/defaultPackage/test/java/DefaultPackageTest.java new file mode 100644 index 0000000000..c3f84b6ab6 --- /dev/null +++ b/integrationtest/src/test/resources/defaultPackage/test/java/DefaultPackageTest.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ + +class DefaultPackageTest { + + @Test + void shouldWorkCorrectlyInDefaultPackage() { + DefaultPackageObject.CarDto carDto = DefaultPackageObject.CarMapper.INSTANCE.carToCarDto( + new DefaultPackageObject.Car( + "Morris", + 5, + DefaultPackageObject.CarType.SEDAN + ) ); + + assertThat( carDto ).isNotNull(); + assertThat( carDto.getMake() ).isEqualTo( "Morris" ); + assertThat( carDto.getSeatCount() ).isEqualTo( 5 ); + assertThat( carDto.getType() ).isEqualTo( "SEDAN" ); + } +} diff --git a/integrationtest/src/test/resources/expressionTextBlocksTest/pom.xml b/integrationtest/src/test/resources/expressionTextBlocksTest/pom.xml new file mode 100644 index 0000000000..b70c48f9d0 --- /dev/null +++ b/integrationtest/src/test/resources/expressionTextBlocksTest/pom.xml @@ -0,0 +1,22 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + expressionTextBlocksTest + jar + + diff --git a/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/Car.java b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/Car.java new file mode 100644 index 0000000000..28d4fd3cd5 --- /dev/null +++ b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/Car.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.textBlocks; + +/** + * @author Filip Hrisafov + */ +public class Car { + + private WheelPosition wheelPosition; + + public WheelPosition getWheelPosition() { + return wheelPosition; + } + + public void setWheelPosition(WheelPosition wheelPosition) { + this.wheelPosition = wheelPosition; + } +} diff --git a/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/CarAndWheelMapper.java b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/CarAndWheelMapper.java new file mode 100644 index 0000000000..23d665c6ff --- /dev/null +++ b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/CarAndWheelMapper.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.textBlocks; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface CarAndWheelMapper { + + CarAndWheelMapper INSTANCE = Mappers.getMapper( CarAndWheelMapper.class ); + + @Mapping(target = "wheelPosition", + expression = + """ + java( + source.getWheelPosition() == null ? + null : + source.getWheelPosition().getPosition() + ) + """) + CarDto carDtoFromCar(Car source); + + @Mapping(target = "wheelPosition", + expression = """ + java( + source.wheelPosition() == null ? + null : + new WheelPosition(source.wheelPosition()) + ) + """) + Car carFromCarDto(CarDto source); +} diff --git a/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/CarDto.java b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/CarDto.java new file mode 100644 index 0000000000..f4baa4d044 --- /dev/null +++ b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/CarDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.textBlocks; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public record CarDto(String wheelPosition) { + +} diff --git a/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/WheelPosition.java b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/WheelPosition.java new file mode 100644 index 0000000000..6effd485a3 --- /dev/null +++ b/integrationtest/src/test/resources/expressionTextBlocksTest/src/main/java/org/mapstruct/itest/textBlocks/WheelPosition.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.textBlocks; + +/** + * @author Filip Hrisafov + */ +public class WheelPosition { + + private final String position; + + public WheelPosition(String position) { + this.position = position; + } + + public String getPosition() { + return position; + } +} diff --git a/integrationtest/src/test/resources/expressionTextBlocksTest/src/test/java/org/mapstruct/itest/textBlocks/TextBlocksTest.java b/integrationtest/src/test/resources/expressionTextBlocksTest/src/test/java/org/mapstruct/itest/textBlocks/TextBlocksTest.java new file mode 100644 index 0000000000..245cf8f304 --- /dev/null +++ b/integrationtest/src/test/resources/expressionTextBlocksTest/src/test/java/org/mapstruct/itest/textBlocks/TextBlocksTest.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.textBlocks; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class TextBlocksTest { + + @Test + void textBlockExpressionShouldWork() { + Car car = new Car(); + car.setWheelPosition( new WheelPosition( "left" ) ); + + CarDto carDto = CarAndWheelMapper.INSTANCE.carDtoFromCar(car); + + assertThat( carDto ).isNotNull(); + assertThat( carDto.wheelPosition() ) + .isEqualTo( "left" ); + } +} diff --git a/integrationtest/src/test/resources/externalbeanjar/beanjar/pom.xml b/integrationtest/src/test/resources/externalbeanjar/beanjar/pom.xml index 58eb8735a3..28ea208e1a 100644 --- a/integrationtest/src/test/resources/externalbeanjar/beanjar/pom.xml +++ b/integrationtest/src/test/resources/externalbeanjar/beanjar/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Source.java b/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Source.java index 36b01ab954..0e6e956efa 100644 --- a/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Source.java +++ b/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.externalbeanjar; diff --git a/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Target.java b/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Target.java index da78a4e03f..26c42e5869 100644 --- a/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Target.java +++ b/integrationtest/src/test/resources/externalbeanjar/beanjar/src/main/java/org/mapstruct/itest/externalbeanjar/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.externalbeanjar; diff --git a/integrationtest/src/test/resources/externalbeanjar/mapper/pom.xml b/integrationtest/src/test/resources/externalbeanjar/mapper/pom.xml index e45abc0302..aa5546f587 100644 --- a/integrationtest/src/test/resources/externalbeanjar/mapper/pom.xml +++ b/integrationtest/src/test/resources/externalbeanjar/mapper/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/externalbeanjar/mapper/src/main/java/org/mapstruct/itest/externalbeanjar/Issue1121Mapper.java b/integrationtest/src/test/resources/externalbeanjar/mapper/src/main/java/org/mapstruct/itest/externalbeanjar/Issue1121Mapper.java index 45d861bde6..35cfacdb89 100644 --- a/integrationtest/src/test/resources/externalbeanjar/mapper/src/main/java/org/mapstruct/itest/externalbeanjar/Issue1121Mapper.java +++ b/integrationtest/src/test/resources/externalbeanjar/mapper/src/main/java/org/mapstruct/itest/externalbeanjar/Issue1121Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /* * To change this license header, choose License Headers in Project Properties. @@ -23,11 +10,11 @@ */ package org.mapstruct.itest.externalbeanjar; -import org.mapstruct.itest.externalbeanjar.Source; -import org.mapstruct.itest.externalbeanjar.Target; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.factory.Mappers; +import org.mapstruct.itest.externalbeanjar.Source; +import org.mapstruct.itest.externalbeanjar.Target; /** * diff --git a/integrationtest/src/test/resources/externalbeanjar/mapper/src/test/java/org/mapstruct/itest/externalbeanjar/ConversionTest.java b/integrationtest/src/test/resources/externalbeanjar/mapper/src/test/java/org/mapstruct/itest/externalbeanjar/ConversionTest.java index 9177041631..5d12c1b0f2 100644 --- a/integrationtest/src/test/resources/externalbeanjar/mapper/src/test/java/org/mapstruct/itest/externalbeanjar/ConversionTest.java +++ b/integrationtest/src/test/resources/externalbeanjar/mapper/src/test/java/org/mapstruct/itest/externalbeanjar/ConversionTest.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; import java.math.BigDecimal; -import static org.assertj.core.api.Assertions.assertThat; -import org.junit.Test; -import org.mapstruct.itest.externalbeanjar.Source; +import org.junit.jupiter.api.Test; import org.mapstruct.itest.externalbeanjar.Issue1121Mapper; +import org.mapstruct.itest.externalbeanjar.Source; import org.mapstruct.itest.externalbeanjar.Target; -public class ConversionTest { +import static org.assertj.core.api.Assertions.assertThat; + +class ConversionTest { @Test - public void shouldApplyConversions() { + void shouldApplyConversions() { Source source = new Source(); source.setBigDecimal( new BigDecimal( "42" ) ); diff --git a/integrationtest/src/test/resources/externalbeanjar/pom.xml b/integrationtest/src/test/resources/externalbeanjar/pom.xml index 9fe0dff28b..ef3bf4da93 100644 --- a/integrationtest/src/test/resources/externalbeanjar/pom.xml +++ b/integrationtest/src/test/resources/externalbeanjar/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/pom.xml b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/pom.xml new file mode 100644 index 0000000000..60b73b856c --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + + org.mapstruct.itest + itest-faultyAstModifyingProcessor-aggregator + 1.0.0 + ../pom.xml + + + itest-faultyAstModifyingProcessor-generator + jar + + + + org.mapstruct + mapstruct-processor + ${mapstruct.version} + provided + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -proc:none + + + + + + + diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/AstModifyingProcessorSaysYes.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/AstModifyingProcessorSaysYes.java new file mode 100644 index 0000000000..e4a5fe5ead --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/AstModifyingProcessorSaysYes.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor; + +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; + +/** + * @author Filip Hrisafov + */ +public class AstModifyingProcessorSaysYes implements AstModifyingAnnotationProcessor { + + @Override + public boolean isTypeComplete(TypeMirror type) { + return true; + } +} diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/FaultyAstModifyingProcessor.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/FaultyAstModifyingProcessor.java new file mode 100644 index 0000000000..ba1be9b2cc --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/FaultyAstModifyingProcessor.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor; + +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; + +/** + * @author Filip Hrisafov + */ +public class FaultyAstModifyingProcessor implements AstModifyingAnnotationProcessor { + + public FaultyAstModifyingProcessor() { + throw new RuntimeException( "Failed to create processor" ); + } + + @Override + public boolean isTypeComplete(TypeMirror type) { + return true; + } +} diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/FaultyStaticAstModifyingProcessor.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/FaultyStaticAstModifyingProcessor.java new file mode 100644 index 0000000000..5f16165014 --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/FaultyStaticAstModifyingProcessor.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor; + +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; + +/** + * @author Filip Hrisafov + */ +public class FaultyStaticAstModifyingProcessor implements AstModifyingAnnotationProcessor { + + static { + if ( true ) { + throw new RuntimeException( "Failed to initialize class" ); + } + } + + @Override + public boolean isTypeComplete(TypeMirror type) { + return true; + } +} diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/resources/META-INF/services/org.mapstruct.ap.spi.AstModifyingAnnotationProcessor b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/resources/META-INF/services/org.mapstruct.ap.spi.AstModifyingAnnotationProcessor new file mode 100644 index 0000000000..3bc4f6138c --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/generator/src/main/resources/META-INF/services/org.mapstruct.ap.spi.AstModifyingAnnotationProcessor @@ -0,0 +1,7 @@ +# Copyright MapStruct Authors. +# +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 +org.mapstruct.itest.faultyAstModifyingProcessor.UnknownAstModifyingProcessor +org.mapstruct.itest.faultyAstModifyingProcessor.AstModifyingProcessorSaysYes +org.mapstruct.itest.faultyAstModifyingProcessor.FaultyAstModifyingProcessor +org.mapstruct.itest.faultyAstModifyingProcessor.FaultyStaticAstModifyingProcessor diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/pom.xml b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/pom.xml new file mode 100644 index 0000000000..dae561252e --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/pom.xml @@ -0,0 +1,27 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + org.mapstruct.itest + itest-faultyAstModifyingProcessor-aggregator + pom + + + generator + usage + + diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/pom.xml b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/pom.xml new file mode 100644 index 0000000000..976664f88d --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + org.mapstruct.itest + itest-faultyAstModifyingProcessor-aggregator + 1.0.0 + ../pom.xml + + + itest-faultyAstModifyingProcessor-usage + jar + + + + org.junit.jupiter + junit-jupiter + test + + + org.mapstruct.itest + itest-faultyAstModifyingProcessor-generator + 1.0.0 + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -XprintProcessorInfo + -XprintRounds + + -proc:none + + + + + diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/Order.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/Order.java new file mode 100644 index 0000000000..1d7cd6380b --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/Order.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor.usage; + +/** + * @author Filip Hrisafov + */ +public class Order { + + private String item; + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } +} diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/OrderDto.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/OrderDto.java new file mode 100644 index 0000000000..afc64606b1 --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/OrderDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor.usage; + +/** + * @author Filip Hrisafov + */ +public class OrderDto { + + private String item; + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } +} diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/OrderMapper.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/OrderMapper.java new file mode 100644 index 0000000000..75e52eb474 --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/main/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/OrderMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor.usage; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface OrderMapper { + + OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class ); + + OrderDto orderToDto(Order order); +} diff --git a/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/test/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/FaultyAstModifyingTestTest.java b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/test/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/FaultyAstModifyingTestTest.java new file mode 100644 index 0000000000..ed6a5c0d89 --- /dev/null +++ b/integrationtest/src/test/resources/faultyAstModifyingAnnotationProcessorTest/usage/src/test/java/org/mapstruct/itest/faultyAstModifyingProcessor/usage/FaultyAstModifyingTestTest.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.faultyAstModifyingProcessor.usage; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for using MapStruct with a faulty AstModifyingProcessor (i.e. when the processor cannot be loaded) + * + * @author Filip Hrisafov + */ +class FaultyAstModifyingTestTest { + + @Test + void testMapping() { + Order order = new Order(); + order.setItem( "my item" ); + + OrderDto dto = OrderMapper.INSTANCE.orderToDto( order ); + assertThat( dto.getItem() ).isEqualTo( "my item" ); + } +} diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/pom.xml b/integrationtest/src/test/resources/freeBuilderBuilderTest/pom.xml index 0b02094fb7..9e8c501ec3 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/pom.xml +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Address.java b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Address.java index 0cc549a778..1b6878fb8c 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Address.java +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.freebuilder; diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/AddressDto.java b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/AddressDto.java index 948efa42e3..053840b441 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/AddressDto.java +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.freebuilder; diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Person.java b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Person.java index 81538dcf60..b4d544d67a 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Person.java +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.freebuilder; diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonDto.java b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonDto.java index e9b2c52e30..3b4a17e591 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonDto.java +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.freebuilder; diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonMapper.java b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonMapper.java index 934a805848..2b732271a3 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonMapper.java +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/main/java/org/mapstruct/itest/freebuilder/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.freebuilder; diff --git a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/test/java/org/mapstruct/itest/freebuilder/FreeBuilderMapperTest.java b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/test/java/org/mapstruct/itest/freebuilder/FreeBuilderMapperTest.java index 0aacabd7a9..3b1caebf9c 100644 --- a/integrationtest/src/test/resources/freeBuilderBuilderTest/src/test/java/org/mapstruct/itest/freebuilder/FreeBuilderMapperTest.java +++ b/integrationtest/src/test/resources/freeBuilderBuilderTest/src/test/java/org/mapstruct/itest/freebuilder/FreeBuilderMapperTest.java @@ -1,24 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.freebuilder; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -27,10 +14,10 @@ * * @author Eric Martineau */ -public class FreeBuilderMapperTest { +class FreeBuilderMapperTest { @Test - public void testSimpleImmutableBuilderHappyPath() { + void testSimpleImmutableBuilderHappyPath() { PersonDto personDto = PersonMapper.INSTANCE.toDto( Person.builder() .setAge( 33 ) .setName( "Bob" ) @@ -45,7 +32,7 @@ public void testSimpleImmutableBuilderHappyPath() { } @Test - public void testLombokToImmutable() { + void testLombokToImmutable() { Person person = PersonMapper.INSTANCE.fromDto( new PersonDto( "Bob", 33, new AddressDto( "Wild Drive" ) ) ); assertThat( person.getAge() ).isEqualTo( 33 ); assertThat( person.getName() ).isEqualTo( "Bob" ); diff --git a/integrationtest/src/test/resources/fullFeatureTest/pom.xml b/integrationtest/src/test/resources/fullFeatureTest/pom.xml index 7625371c21..670d5cff92 100644 --- a/integrationtest/src/test/resources/fullFeatureTest/pom.xml +++ b/integrationtest/src/test/resources/fullFeatureTest/pom.xml @@ -1,22 +1,9 @@ @@ -37,6 +24,14 @@ x x x + x + x + x + x + x + x + x + x @@ -52,10 +47,21 @@ **/*Test.java **/testutil/**/*.java **/spi/**/*.java + **/kotlin/**/*.java ${additionalExclude0} ${additionalExclude1} ${additionalExclude2} ${additionalExclude3} + ${additionalExclude4} + ${additionalExclude5} + ${additionalExclude6} + ${additionalExclude7} + ${additionalExclude8} + ${additionalExclude9} + ${additionalExclude10} + ${additionalExclude11} + ${additionalExclude12} + ${additionalExclude13} @@ -71,6 +77,14 @@ javax.inject javax.inject + + jakarta.inject + jakarta.inject-api + + + jakarta.enterprise + jakarta.enterprise.cdi-api + @@ -86,5 +100,35 @@ joda-time joda-time + + + jakarta.xml.bind + jakarta.xml.bind-api + provided + true + + + + + jdk-11-or-newer + + [11 + + + + javax.xml.bind + jaxb-api + provided + true + + + org.glassfish.jaxb + jaxb-runtime + provided + true + + + + diff --git a/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java b/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java index 26147bdf7b..4f2d7bd9ed 100644 --- a/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java +++ b/integrationtest/src/test/resources/fullFeatureTest/src/test/java/org/mapstruct/itest/simple/AnimalTest.java @@ -1,40 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; - -import org.mapstruct.ap.test.ignore.AnimalMapper; +import org.junit.jupiter.api.Test; import org.mapstruct.ap.test.ignore.Animal; import org.mapstruct.ap.test.ignore.AnimalDto; +import org.mapstruct.ap.test.ignore.AnimalMapper; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for ignoring properties during the mapping. * * @author Gunnar Morling */ -public class AnimalTest { +class AnimalTest { @Test - public void shouldNotPropagateIgnoredPropertyGivenViaTargetAttribute() { + void shouldNotPropagateIgnoredPropertyGivenViaTargetAttribute() { Animal animal = new Animal( "Bruno", 100, 23, "black" ); AnimalDto animalDto = AnimalMapper.INSTANCE.animalToDto( animal ); @@ -47,7 +33,7 @@ public void shouldNotPropagateIgnoredPropertyGivenViaTargetAttribute() { } @Test - public void shouldNotPropagateIgnoredPropertyInReverseMappingWhenSourceAndTargetAreSpecified() { + void shouldNotPropagateIgnoredPropertyInReverseMappingWhenSourceAndTargetAreSpecified() { AnimalDto animalDto = new AnimalDto( "Bruno", 100, 23, "black" ); Animal animal = AnimalMapper.INSTANCE.animalDtoToAnimal( animalDto ); diff --git a/integrationtest/src/test/resources/gradleIncrementalCompilationTest/build.gradle b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/build.gradle new file mode 100644 index 0000000000..0df032f0f2 --- /dev/null +++ b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/build.gradle @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +plugins { + id 'java' +} + +if (!project.hasProperty('mapstructRootPath')) + throw new IllegalArgumentException("Missing required property: mapstructRootPath") + +repositories { + jcenter() + mavenLocal() + flatDir { + dirs "${mapstructRootPath}/processor/target" + dirs "${mapstructRootPath}/core/target" + } +} + +// Extract version and artifactId values +def apPom = new XmlParser().parse(file("${mapstructRootPath}/processor/pom.xml")) +ext.apArtifactId = apPom.artifactId[0].text() +ext.apVersion = apPom.parent[0].version[0].text() + +def libPom = new XmlParser().parse(file("${mapstructRootPath}/core/pom.xml")) +ext.libArtifactId = libPom.artifactId[0].text() +ext.libVersion = libPom.parent[0].version[0].text() + +dependencies { + annotationProcessor name: "${apArtifactId}-${apVersion}" + implementation name: "${libArtifactId}-${libVersion}" +} diff --git a/integrationtest/src/test/resources/gradleIncrementalCompilationTest/settings.gradle b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/settings.gradle new file mode 100644 index 0000000000..b6ca918e91 --- /dev/null +++ b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/settings.gradle @@ -0,0 +1,6 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +rootProject.name = 'gradle-incremental-compilation-test' \ No newline at end of file diff --git a/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/TestMapper.java b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/TestMapper.java new file mode 100644 index 0000000000..52c64051f1 --- /dev/null +++ b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/TestMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.gradle.lib; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.itest.gradle.model.Source; +import org.mapstruct.itest.gradle.model.Target; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface TestMapper { + @Mapping(target = "field", source = "value") + public Target toTarget(Source source); +} diff --git a/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/UnrelatedComponent.java b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/UnrelatedComponent.java new file mode 100644 index 0000000000..9f1095850c --- /dev/null +++ b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/lib/UnrelatedComponent.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.gradle.lib; + +public class UnrelatedComponent { + public boolean unrelatedMethod() { + return true; + } +} diff --git a/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Source.java b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Source.java new file mode 100644 index 0000000000..c7103aaceb --- /dev/null +++ b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Source.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.gradle.model; + +public class Source { + private int value; + + public void setValue(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Target.java b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Target.java new file mode 100644 index 0000000000..4b5a171109 --- /dev/null +++ b/integrationtest/src/test/resources/gradleIncrementalCompilationTest/src/main/java/org/mapstruct/itest/gradle/model/Target.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.gradle.model; + +public class Target { + private String field = getDefaultValue(); + private String otherField; + + public void setField(String field) { + this.field = field; + } + + public String getField() { + return field; + } + + public void setOtherField(String otherField) { + this.otherField = otherField; + } + + public String getOtherField() { + return otherField; + } + + public String getDefaultValue() { + return "original"; + } +} diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/extras/pom.xml b/integrationtest/src/test/resources/immutablesBuilderTest/extras/pom.xml index c7f6a13f92..5141f2998b 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/extras/pom.xml +++ b/integrationtest/src/test/resources/immutablesBuilderTest/extras/pom.xml @@ -1,4 +1,11 @@ + diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/pom.xml b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/pom.xml index cbe79c972e..10c481b66e 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/pom.xml +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/pom.xml @@ -1,4 +1,11 @@ + diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Address.java b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Address.java index 2e96845e6f..ce9c033ad0 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Address.java +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.immutables; diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/AddressDto.java b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/AddressDto.java index 7accf8559b..0f24e182f5 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/AddressDto.java +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.immutables; diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Person.java b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Person.java index 2951023942..dfbfc47b74 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Person.java +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.immutables; diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonDto.java b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonDto.java index 99027926bb..44a6b7b9e3 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonDto.java +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.immutables; diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonMapper.java b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonMapper.java index b52821fe6f..6023833ec8 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonMapper.java +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/main/java/org/mapstruct/itest/immutables/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.immutables; diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/test/java/org/mapstruct/itest/immutables/ImmutablesMapperTest.java b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/test/java/org/mapstruct/itest/immutables/ImmutablesMapperTest.java index 9b526f1a54..9990f4278c 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/test/java/org/mapstruct/itest/immutables/ImmutablesMapperTest.java +++ b/integrationtest/src/test/resources/immutablesBuilderTest/mapper/src/test/java/org/mapstruct/itest/immutables/ImmutablesMapperTest.java @@ -1,24 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.immutables; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -27,10 +14,10 @@ * * @author Eric Martineau */ -public class ImmutablesMapperTest { +class ImmutablesMapperTest { @Test - public void testSimpleImmutableBuilderHappyPath() { + void testSimpleImmutableBuilderHappyPath() { PersonDto personDto = PersonMapper.INSTANCE.toDto( ImmutablePerson.builder() .age( 33 ) .name( "Bob" ) @@ -45,7 +32,7 @@ public void testSimpleImmutableBuilderHappyPath() { } @Test - public void testLombokToImmutable() { + void testLombokToImmutable() { Person person = PersonMapper.INSTANCE.fromDto( new PersonDto( "Bob", 33, new AddressDto( "Wild Drive" ) ) ); assertThat( person.getAge() ).isEqualTo( 33 ); assertThat( person.getName() ).isEqualTo( "Bob" ); diff --git a/integrationtest/src/test/resources/immutablesBuilderTest/pom.xml b/integrationtest/src/test/resources/immutablesBuilderTest/pom.xml index 19a738894d..51542adbcb 100644 --- a/integrationtest/src/test/resources/immutablesBuilderTest/pom.xml +++ b/integrationtest/src/test/resources/immutablesBuilderTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/pom.xml b/integrationtest/src/test/resources/jakartaJaxbTest/pom.xml new file mode 100644 index 0000000000..3a2d0351ce --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/pom.xml @@ -0,0 +1,64 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + jakartaJaxbTest + jar + + + + jakarta.xml.bind + jakarta.xml.bind-api + provided + true + + + com.sun.xml.bind + jaxb-impl + provided + true + + + + + + + org.codehaus.mojo + jaxb2-maven-plugin + 3.1.0 + + + xjc + initialize + + xjc + + + + + + \${project.build.resources[0].directory}/binding + + + \${project.build.resources[0].directory}/schema + + + + + + diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderDetailsDto.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderDetailsDto.java new file mode 100644 index 0000000000..e8500633e4 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderDetailsDto.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +import java.util.List; + +/** + * @author Sjaak Derksen + */ +public class OrderDetailsDto { + + private String name; + private List description; + private OrderStatusDto status; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getDescription() { + return description; + } + + public void setDescription(List description) { + this.description = description; + } + + public OrderStatusDto getStatus() { + return status; + } + + public void setStatus(OrderStatusDto status) { + this.status = status; + } +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderDto.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderDto.java new file mode 100644 index 0000000000..f94d5362ef --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderDto.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +import java.util.Date; + +/** + * @author Sjaak Derksen + */ +public class OrderDto { + + private Long orderNumber; + private Date orderDate; + private OrderDetailsDto orderDetails; + private ShippingAddressDto shippingAddress; + + public Long getOrderNumber() { + return orderNumber; + } + + public void setOrderNumber(Long orderNumber) { + this.orderNumber = orderNumber; + } + + public Date getOrderDate() { + return orderDate; + } + + public void setOrderDate(Date orderDate) { + this.orderDate = orderDate; + } + + public OrderDetailsDto getOrderDetails() { + return orderDetails; + } + + public void setOrderDetails(OrderDetailsDto orderDetails) { + this.orderDetails = orderDetails; + } + + public ShippingAddressDto getShippingAddress() { + return shippingAddress; + } + + public void setShippingAddress(ShippingAddressDto shippingAddress) { + this.shippingAddress = shippingAddress; + } + +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderStatusDto.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderStatusDto.java new file mode 100644 index 0000000000..5da5d45c99 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/OrderStatusDto.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +/** + * @author Sjaak Derksen + */ +public enum OrderStatusDto { + + ORDERED( "small" ), + PROCESSED( "medium" ), + DELIVERED( "large" ); + private final String value; + + OrderStatusDto(String v) { + value = v; + } + + public String value() { + return value; + } + + public static OrderStatusDto fromValue(String v) { + for ( OrderStatusDto c : OrderStatusDto.values() ) { + if ( c.value.equals( v ) ) { + return c; + } + } + throw new IllegalArgumentException( v ); + } + +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/ShippingAddressDto.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/ShippingAddressDto.java new file mode 100644 index 0000000000..6bc40a19b2 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/ShippingAddressDto.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +/** + * @author Sjaak Derksen + */ +public class ShippingAddressDto { + + private String street; + private String houseNumber; + private String city; + private String country; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + public String getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber(String houseNumber) { + this.houseNumber = houseNumber; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SourceTargetMapper.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SourceTargetMapper.java new file mode 100644 index 0000000000..8356f76192 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SourceTargetMapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.mapstruct.itest.jakarta.jaxb.xsd.test1.OrderDetailsType; +import org.mapstruct.itest.jakarta.jaxb.xsd.test1.OrderType; +import org.mapstruct.itest.jakarta.jaxb.xsd.test2.OrderStatusType; +import org.mapstruct.itest.jakarta.jaxb.xsd.test2.ShippingAddressType; +import org.mapstruct.itest.jakarta.jaxb.xsd.underscores.SubType; + +/** + * @author Sjaak Derksen + */ +@Mapper(uses = { + org.mapstruct.itest.jakarta.jaxb.xsd.test1.ObjectFactory.class, + org.mapstruct.itest.jakarta.jaxb.xsd.test2.ObjectFactory.class, + org.mapstruct.itest.jakarta.jaxb.xsd.underscores.ObjectFactory.class +}) +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + // source 2 target methods + OrderDto sourceToTarget(OrderType source); + + OrderDetailsDto detailsToDto(OrderDetailsType source); + + OrderStatusDto statusToDto(OrderStatusType source); + + ShippingAddressDto shippingAddressToDto(ShippingAddressType source); + + SubTypeDto subTypeToDto(SubType source); + + // target 2 source methods + OrderType targetToSource(OrderDto target); + + OrderDetailsType dtoToDetails(OrderDetailsDto target); + + OrderStatusType dtoToStatus(OrderStatusDto target); + + ShippingAddressType dtoToShippingAddress(ShippingAddressDto source); + + SubType dtoToSubType(SubTypeDto source); +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SubTypeDto.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SubTypeDto.java new file mode 100644 index 0000000000..88218c2771 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SubTypeDto.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +public class SubTypeDto extends SuperTypeDto { + private String declaredCamelCase; + private String declaredUnderscore; + + public String getDeclaredCamelCase() { + return declaredCamelCase; + } + + public void setDeclaredCamelCase(String declaredCamelCase) { + this.declaredCamelCase = declaredCamelCase; + } + + public String getDeclaredUnderscore() { + return declaredUnderscore; + } + + public void setDeclaredUnderscore(String declaredUnderscore) { + this.declaredUnderscore = declaredUnderscore; + } +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SuperTypeDto.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SuperTypeDto.java new file mode 100644 index 0000000000..cd0c6e22e7 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/java/org/mapstruct/itest/jakarta/jaxb/SuperTypeDto.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +public class SuperTypeDto { + private String inheritedCamelCase; + private String inheritedUnderscore; + + public String getInheritedCamelCase() { + return inheritedCamelCase; + } + + public void setInheritedCamelCase(String inheritedCamelCase) { + this.inheritedCamelCase = inheritedCamelCase; + } + + public String getInheritedUnderscore() { + return inheritedUnderscore; + } + + public void setInheritedUnderscore(String inheritedUnderscore) { + this.inheritedUnderscore = inheritedUnderscore; + } +} diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/binding/binding.xjb b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/binding/binding.xjb new file mode 100644 index 0000000000..8f26b1a1ea --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/binding/binding.xjb @@ -0,0 +1,28 @@ + + + + + + + + + + + + + diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/test1.xsd b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/test1.xsd new file mode 100644 index 0000000000..3433b01465 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/test1.xsd @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/test2.xsd b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/test2.xsd new file mode 100644 index 0000000000..f3b564a48e --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/test2.xsd @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/underscores.xsd b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/underscores.xsd new file mode 100644 index 0000000000..b7f5904656 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/main/resources/schema/underscores.xsd @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/integrationtest/src/test/resources/jakartaJaxbTest/src/test/java/org/mapstruct/itest/jakarta/jaxb/JakartaJaxbBasedMapperTest.java b/integrationtest/src/test/resources/jakartaJaxbTest/src/test/java/org/mapstruct/itest/jakarta/jaxb/JakartaJaxbBasedMapperTest.java new file mode 100644 index 0000000000..78e051a4e9 --- /dev/null +++ b/integrationtest/src/test/resources/jakartaJaxbTest/src/test/java/org/mapstruct/itest/jakarta/jaxb/JakartaJaxbBasedMapperTest.java @@ -0,0 +1,117 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.jakarta.jaxb; + +import java.io.ByteArrayOutputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; + +import jakarta.xml.bind.JAXBContext; +import jakarta.xml.bind.JAXBElement; +import jakarta.xml.bind.JAXBException; +import jakarta.xml.bind.Marshaller; +import org.junit.jupiter.api.Test; +import org.mapstruct.itest.jakarta.jaxb.xsd.test1.ObjectFactory; +import org.mapstruct.itest.jakarta.jaxb.xsd.test1.OrderType; +import org.mapstruct.itest.jakarta.jaxb.xsd.underscores.SubType; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for generation of Jakarta JAXB based mapper implementations. + * + * @author Iaroslav Bogdanchikov + */ +class JakartaJaxbBasedMapperTest { + + @Test + void shouldMapJakartaJaxb() throws ParseException, JAXBException { + + SourceTargetMapper mapper = SourceTargetMapper.INSTANCE; + + OrderDto source1 = new OrderDto(); + source1.setOrderDetails( new OrderDetailsDto() ); + source1.setOrderNumber( 11L ); + source1.setOrderDate( createDate( "31-08-1982 10:20:56" ) ); + source1.setShippingAddress( new ShippingAddressDto() ); + source1.getShippingAddress().setCity( "SmallTown" ); + source1.getShippingAddress().setHouseNumber( "11a" ); + source1.getShippingAddress().setStreet( "Awesome rd" ); + source1.getShippingAddress().setCountry( "USA" ); + source1.getOrderDetails().setDescription( new ArrayList() ); + source1.getOrderDetails().setName( "Shopping list for a Mapper" ); + source1.getOrderDetails().getDescription().add( "1 MapStruct" ); + source1.getOrderDetails().getDescription().add( "3 Lines of Code" ); + source1.getOrderDetails().getDescription().add( "1 Dose of Luck" ); + source1.getOrderDetails().setStatus( OrderStatusDto.ORDERED ); + + // map to JAXB + OrderType target = mapper.targetToSource( source1 ); + + // do a pretty print + ObjectFactory of = new ObjectFactory(); + System.out.println( toXml( of.createOrder( target ) ) ); + + // map back from JAXB + OrderDto source2 = mapper.sourceToTarget( target ); + + // verify that source1 and source 2 are equal + assertThat( source2.getOrderNumber() ).isEqualTo( source1.getOrderNumber() ); + assertThat( source2.getOrderDate() ).isEqualTo( source1.getOrderDate() ); + assertThat( source2.getOrderDetails().getDescription().size() ).isEqualTo( + source1.getOrderDetails().getDescription().size() + ); + assertThat( source2.getOrderDetails().getDescription().get( 0 ) ).isEqualTo( + source1.getOrderDetails().getDescription().get( 0 ) + ); + assertThat( source2.getOrderDetails().getDescription().get( 1 ) ).isEqualTo( + source1.getOrderDetails().getDescription().get( 1 ) + ); + assertThat( source2.getOrderDetails().getDescription().get( 2 ) ).isEqualTo( + source1.getOrderDetails().getDescription().get( 2 ) + ); + assertThat( source2.getOrderDetails().getName() ).isEqualTo( source1.getOrderDetails().getName() ); + assertThat( source2.getOrderDetails().getStatus() ).isEqualTo( source1.getOrderDetails().getStatus() ); + } + + @Test + void underscores() throws ParseException, JAXBException { + + SourceTargetMapper mapper = SourceTargetMapper.INSTANCE; + + SubTypeDto source1 = new SubTypeDto(); + source1.setInheritedCamelCase("InheritedCamelCase"); + source1.setInheritedUnderscore("InheritedUnderscore"); + source1.setDeclaredCamelCase("DeclaredCamelCase"); + source1.setDeclaredUnderscore("DeclaredUnderscore"); + + SubType target = mapper.dtoToSubType( source1 ); + + SubTypeDto source2 = mapper.subTypeToDto( target ); + + assertThat( source2.getInheritedCamelCase() ).isEqualTo( source1.getInheritedCamelCase() ); + assertThat( source2.getInheritedUnderscore() ).isEqualTo( source1.getInheritedUnderscore() ); + assertThat( source2.getDeclaredCamelCase() ).isEqualTo( source1.getDeclaredCamelCase() ); + assertThat( source2.getDeclaredUnderscore() ).isEqualTo( source1.getDeclaredUnderscore() ); + } + + private Date createDate(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" ); + return sdf.parse( date ); + } + + private String toXml(JAXBElement element) throws JAXBException { + JAXBContext jc = JAXBContext.newInstance( element.getValue().getClass() ); + Marshaller marshaller = jc.createMarshaller(); + marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE ); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + marshaller.marshal( element, baos ); + return baos.toString(); + } +} diff --git a/integrationtest/src/test/resources/java8Test/pom.xml b/integrationtest/src/test/resources/java8Test/pom.xml index f9367676c7..face2f4564 100644 --- a/integrationtest/src/test/resources/java8Test/pom.xml +++ b/integrationtest/src/test/resources/java8Test/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Source.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Source.java index b27a00f778..76925c4430 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Source.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._603; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapper.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapper.java index 9f19f94b79..129c459816 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._603; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapperDecorator.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapperDecorator.java index a9d9c2898e..7d47b1f836 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapperDecorator.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/SourceTargetMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._603; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Target.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Target.java index 2e7b68a2bd..d1511d7fdb 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Target.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_603/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._603; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Bar.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Bar.java index 2a94d20c04..54a360f7e3 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Bar.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Bar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Foo.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Foo.java index c4aed965ec..80c01d4fd6 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Foo.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Source.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Source.java index 322bb9ba02..e7a44792e9 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Source.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetBaseMapper.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetBaseMapper.java index 314e4c2377..2b09b1e59e 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetBaseMapper.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetBaseMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; @@ -23,6 +10,11 @@ @Mapper public interface SourceTargetBaseMapper { - // TODO.. move default and static interface method here when problem in eclipse processor is fixed. + default Foo fooFromId(long id) { + return new Foo(id); + } + static Bar barFromId(String id) { + return new Bar(id); + } } diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetMapper.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetMapper.java index 4705a58910..85102e1918 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; @@ -28,17 +15,8 @@ public interface SourceTargetMapper extends SourceTargetBaseMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mappings({ - @Mapping(source = "idFoo", target = "foo"), - @Mapping(source = "idBar", target = "bar") + @Mapping(target = "foo", source = "idFoo"), + @Mapping(target = "bar", source = "idBar") }) Target mapSourceToTarget(Source source); - - default Foo fooFromId(long id) { - return new Foo(id); - } - - static Bar barFromId(String id) { - return new Bar(id); - } - } diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Target.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Target.java index 9046c7e155..5a45d57d1f 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Target.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/ap/test/bugs/_636/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Java8Mapper.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Java8Mapper.java index 6ffb9b0c11..f16228b60e 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Java8Mapper.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Java8Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.java8; @@ -27,7 +14,7 @@ public interface Java8Mapper { Java8Mapper INSTANCE = Mappers.getMapper( Java8Mapper.class ); - @Mapping(source = "firstName", target = "givenName") - @Mapping(source = "lastName", target = "surname") + @Mapping(target = "givenName", source = "firstName") + @Mapping(target = "surname", source = "lastName") Target sourceToTarget(Source source); } diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Source.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Source.java index 64ac073f27..4f25c4a89b 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Source.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.java8; diff --git a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Target.java b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Target.java index f219cb7fe0..d738aa37ac 100644 --- a/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Target.java +++ b/integrationtest/src/test/resources/java8Test/src/main/java/org/mapstruct/itest/java8/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.java8; diff --git a/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_603/Issue603Test.java b/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_603/Issue603Test.java index 84072f85b3..efe68a48ee 100644 --- a/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_603/Issue603Test.java +++ b/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_603/Issue603Test.java @@ -1,32 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._603; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -public class Issue603Test { +class Issue603Test { @Test - public void shouldMapDataFromJava8Interface() { + void shouldMapDataFromJava8Interface() { final Source source = new Source(); diff --git a/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_636/Issue636Test.java b/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_636/Issue636Test.java index 584f0e42c4..837eb0b53a 100644 --- a/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_636/Issue636Test.java +++ b/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/ap/test/bugs/_636/Issue636Test.java @@ -1,31 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._636; -import org.junit.Test; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; -public class Issue636Test { +class Issue636Test { @Test - public void shouldMapDataFromJava8Interface() { + void shouldMapDataFromJava8Interface() { final long idFoo = 123; final String idBar = "Bar456"; diff --git a/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/itest/java8/Java8MapperTest.java b/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/itest/java8/Java8MapperTest.java index d1f3b74668..4a390628af 100644 --- a/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/itest/java8/Java8MapperTest.java +++ b/integrationtest/src/test/resources/java8Test/src/test/java/org/mapstruct/itest/java8/Java8MapperTest.java @@ -1,36 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.java8; -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.Test; -import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; /** * Test for generation of Java8 based mapper implementations. * * @author Christian Schuster */ -public class Java8MapperTest { +class Java8MapperTest { @Test - public void shouldMapWithRepeatedMappingAnnotation() { + void shouldMapWithRepeatedMappingAnnotation() { Java8Mapper mapper = Java8Mapper.INSTANCE; Source source = new Source(); diff --git a/integrationtest/src/test/resources/jaxbTest/pom.xml b/integrationtest/src/test/resources/jaxbTest/pom.xml index 2f6be7fe29..0e69e23e01 100644 --- a/integrationtest/src/test/resources/jaxbTest/pom.xml +++ b/integrationtest/src/test/resources/jaxbTest/pom.xml @@ -1,22 +1,9 @@ true 2.1 + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + + + + + + jdk-11-or-newer + + [11 + + + + javax.xml.bind + jaxb-api + provided + true + + + org.glassfish.jaxb + jaxb-runtime + provided + true + + + + + diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/JaxbMapper.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/JaxbMapper.java deleted file mode 100644 index ab8905d3e7..0000000000 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/JaxbMapper.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.itest.jaxb; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.JAXBElement; - -import org.mapstruct.itest.jaxb.xsd.test1.ObjectFactory; - -/** - * This class can be removed as soon as MapStruct is capable of generating List mappings. - * - * @author Sjaak Derksen - */ -public class JaxbMapper { - - private final ObjectFactory of = new ObjectFactory(); - - /** - * This method is needed, because currently MapStruct is not capable of selecting - * the proper factory method for Lists - * - * @param orderDetailsDescriptions - * - * @return - */ - List> toJaxbList(List orderDetailsDescriptions) { - - List> result = new ArrayList>(); - for ( String orderDetailDescription : orderDetailsDescriptions ) { - result.add( of.createOrderDetailsTypeDescription( orderDetailDescription ) ); - } - return result; - } - -} diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDetailsDto.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDetailsDto.java index cdfea57e8c..9350344d56 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDetailsDto.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDetailsDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDto.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDto.java index f6569e51e2..e8d268a7ac 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDto.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderStatusDto.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderStatusDto.java index 0930e2b930..df87932d73 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderStatusDto.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/OrderStatusDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/ShippingAddressDto.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/ShippingAddressDto.java index a4c91a2456..6c2b033c5b 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/ShippingAddressDto.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/ShippingAddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SourceTargetMapper.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SourceTargetMapper.java index 76f6d5bcf2..49dab0092f 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; @@ -26,15 +13,13 @@ import org.mapstruct.itest.jaxb.xsd.test2.ShippingAddressType; import org.mapstruct.itest.jaxb.xsd.underscores.SubType; - /** * @author Sjaak Derksen */ @Mapper(uses = { org.mapstruct.itest.jaxb.xsd.test1.ObjectFactory.class, org.mapstruct.itest.jaxb.xsd.test2.ObjectFactory.class, - org.mapstruct.itest.jaxb.xsd.underscores.ObjectFactory.class, - JaxbMapper.class + org.mapstruct.itest.jaxb.xsd.underscores.ObjectFactory.class }) public interface SourceTargetMapper { diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SubTypeDto.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SubTypeDto.java index 1fca5b9e53..affa8e3536 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SubTypeDto.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SubTypeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SuperTypeDto.java b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SuperTypeDto.java index aebf35312c..f07875e8ee 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SuperTypeDto.java +++ b/integrationtest/src/test/resources/jaxbTest/src/main/java/org/mapstruct/itest/jaxb/SuperTypeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jaxb; diff --git a/integrationtest/src/test/resources/jaxbTest/src/main/resources/binding/binding.xjb b/integrationtest/src/test/resources/jaxbTest/src/main/resources/binding/binding.xjb index 8c35a5b844..3d5129c5e4 100644 --- a/integrationtest/src/test/resources/jaxbTest/src/main/resources/binding/binding.xjb +++ b/integrationtest/src/test/resources/jaxbTest/src/main/resources/binding/binding.xjb @@ -1,22 +1,9 @@ @@ -31,6 +18,10 @@ jsr330Test jar + + + ${org.junit6.jupiter.version} + @@ -47,8 +38,8 @@ spring-context - javax.inject - javax.inject + jakarta.inject + jakarta.inject-api diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java index f9c45a442a..3f04abd7df 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/DecoratedSourceTargetMapper.java @@ -1,28 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; -import org.mapstruct.Mapper; import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.jsr330.other.DateMapper; -@Mapper(componentModel = "jsr330", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = DateMapper.class) @DecoratedWith(SourceTargetMapperDecorator.class) public interface DecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java index 4305d49366..edfaeb3171 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondDecoratedSourceTargetMapper.java @@ -1,28 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; -import org.mapstruct.Mapper; import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.jsr330.other.DateMapper; -@Mapper(componentModel = "jsr330", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = DateMapper.class) @DecoratedWith(SecondSourceTargetMapperDecorator.class) public interface SecondDecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondSourceTargetMapperDecorator.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondSourceTargetMapperDecorator.java index fa8b8388e2..0fb513c99b 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondSourceTargetMapperDecorator.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SecondSourceTargetMapperDecorator.java @@ -1,25 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; -import javax.inject.Inject; -import javax.inject.Named; +import jakarta.inject.Inject; +import jakarta.inject.Named; public abstract class SecondSourceTargetMapperDecorator implements SecondDecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Source.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Source.java index 91f8ac8f55..6edf1e5133 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Source.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java index d3c9078cdb..a96a860da5 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapper.java @@ -1,27 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.jsr330.other.DateMapper; -@Mapper(componentModel = "jsr330", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = DateMapper.class) public interface SourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapperDecorator.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapperDecorator.java index 6fd5bd83a6..7f4b968227 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapperDecorator.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/SourceTargetMapperDecorator.java @@ -1,25 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; -import javax.inject.Inject; -import javax.inject.Named; +import jakarta.inject.Inject; +import jakarta.inject.Named; public abstract class SourceTargetMapperDecorator implements DecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Target.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Target.java index 8411101d9e..b3efb96456 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Target.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; diff --git a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/other/DateMapper.java b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/other/DateMapper.java index 0b8e440a4c..d97b168776 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/other/DateMapper.java +++ b/integrationtest/src/test/resources/jsr330Test/src/main/java/org/mapstruct/itest/jsr330/other/DateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330.other; @@ -22,8 +9,8 @@ import java.text.SimpleDateFormat; import java.util.Date; -import javax.inject.Named; -import javax.inject.Singleton; +import jakarta.inject.Named; +import jakarta.inject.Singleton; @Singleton @Named diff --git a/integrationtest/src/test/resources/jsr330Test/src/test/java/org/mapstruct/itest/jsr330/Jsr330BasedMapperTest.java b/integrationtest/src/test/resources/jsr330Test/src/test/java/org/mapstruct/itest/jsr330/Jsr330BasedMapperTest.java index c48fe16718..7196051ff8 100644 --- a/integrationtest/src/test/resources/jsr330Test/src/test/java/org/mapstruct/itest/jsr330/Jsr330BasedMapperTest.java +++ b/integrationtest/src/test/resources/jsr330Test/src/test/java/org/mapstruct/itest/jsr330/Jsr330BasedMapperTest.java @@ -1,33 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.jsr330; -import javax.inject.Inject; -import javax.inject.Named; - -import org.junit.Test; -import org.junit.runner.RunWith; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.itest.jsr330.Jsr330BasedMapperTest.SpringTestConfig; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -37,8 +23,8 @@ * @author Andreas Gudian */ @ContextConfiguration(classes = SpringTestConfig.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class Jsr330BasedMapperTest { +@ExtendWith(SpringExtension.class) +class Jsr330BasedMapperTest { @Configuration @ComponentScan(basePackageClasses = Jsr330BasedMapperTest.class) public static class SpringTestConfig { @@ -56,7 +42,7 @@ public static class SpringTestConfig { private SecondDecoratedSourceTargetMapper secondDecoratedMapper; @Test - public void shouldInjectJsr330BasedMapper() { + void shouldInjectJsr330BasedMapper() { Source source = new Source(); Target target = mapper.sourceToTarget( source ); @@ -67,7 +53,7 @@ public void shouldInjectJsr330BasedMapper() { } @Test - public void shouldInjectDecorator() { + void shouldInjectDecorator() { Source source = new Source(); Target target = decoratedMapper.sourceToTarget( source ); @@ -84,7 +70,7 @@ public void shouldInjectDecorator() { } @Test - public void shouldInjectSecondDecorator() { + void shouldInjectSecondDecorator() { Source source = new Source(); Target target = secondDecoratedMapper.sourceToTarget( source ); diff --git a/integrationtest/src/test/resources/kotlinDataTest/pom.xml b/integrationtest/src/test/resources/kotlinDataTest/pom.xml new file mode 100644 index 0000000000..f86f92b9c4 --- /dev/null +++ b/integrationtest/src/test/resources/kotlinDataTest/pom.xml @@ -0,0 +1,102 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + kotlinDataTest + jar + + + 1.6.0 + + + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + + + + generate-via-compiler-plugin + + false + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + + compile + compile + + + \${project.basedir}/src/main/kotlin + \${project.basedir}/src/main/java + + + + + test-compile + test-compile + + + \${project.basedir}/src/test/kotlin + \${project.basedir}/src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + default-compile + none + + + + default-testCompile + none + + + java-compile + compile + compile + + + java-test-compile + test-compile + testCompile + + + + + + + + + diff --git a/integrationtest/src/test/resources/kotlinDataTest/src/main/java/org/mapstruct/itest/kotlin/data/CustomerEntity.java b/integrationtest/src/test/resources/kotlinDataTest/src/main/java/org/mapstruct/itest/kotlin/data/CustomerEntity.java new file mode 100644 index 0000000000..e992eb0e60 --- /dev/null +++ b/integrationtest/src/test/resources/kotlinDataTest/src/main/java/org/mapstruct/itest/kotlin/data/CustomerEntity.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.kotlin.data; + +/** + * @author Filip Hrisafov + */ +public class CustomerEntity { + + private String name; + private String mail; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } +} diff --git a/integrationtest/src/test/resources/kotlinDataTest/src/main/java/org/mapstruct/itest/kotlin/data/CustomerMapper.java b/integrationtest/src/test/resources/kotlinDataTest/src/main/java/org/mapstruct/itest/kotlin/data/CustomerMapper.java new file mode 100644 index 0000000000..b2157252db --- /dev/null +++ b/integrationtest/src/test/resources/kotlinDataTest/src/main/java/org/mapstruct/itest/kotlin/data/CustomerMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.kotlin.data; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "mail", source = "email") + CustomerEntity fromRecord(CustomerDto record); + + @InheritInverseConfiguration + CustomerDto toRecord(CustomerEntity entity); + +} diff --git a/integrationtest/src/test/resources/kotlinDataTest/src/main/kotlin/org/mapstruct/itest/kotlin/data/CustomerDto.kt b/integrationtest/src/test/resources/kotlinDataTest/src/main/kotlin/org/mapstruct/itest/kotlin/data/CustomerDto.kt new file mode 100644 index 0000000000..820a8b56c3 --- /dev/null +++ b/integrationtest/src/test/resources/kotlinDataTest/src/main/kotlin/org/mapstruct/itest/kotlin/data/CustomerDto.kt @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.kotlin.data; + +data class CustomerDto(var name: String?, var email: String?) { + +} diff --git a/integrationtest/src/test/resources/kotlinDataTest/src/test/java/org/mapstruct/itest/kotlin/data/KotlinDataTest.java b/integrationtest/src/test/resources/kotlinDataTest/src/test/java/org/mapstruct/itest/kotlin/data/KotlinDataTest.java new file mode 100644 index 0000000000..39bb909746 --- /dev/null +++ b/integrationtest/src/test/resources/kotlinDataTest/src/test/java/org/mapstruct/itest/kotlin/data/KotlinDataTest.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.kotlin.data; + +import org.junit.jupiter.api.Test; +import org.mapstruct.itest.kotlin.data.CustomerDto; +import org.mapstruct.itest.kotlin.data.CustomerEntity; +import org.mapstruct.itest.kotlin.data.CustomerMapper; + +import static org.assertj.core.api.Assertions.assertThat; + +class KotlinDataTest { + + @Test + void shouldMapData() { + CustomerEntity customer = CustomerMapper.INSTANCE.fromRecord( new CustomerDto( "Kermit", "kermit@test.com" ) ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getMail() ).isEqualTo( "kermit@test.com" ); + } + + @Test + void shouldMapIntoData() { + CustomerEntity entity = new CustomerEntity(); + entity.setName( "Kermit" ); + entity.setMail( "kermit@test.com" ); + + CustomerDto customer = CustomerMapper.INSTANCE.toRecord( entity ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getEmail() ).isEqualTo( "kermit@test.com" ); + } +} diff --git a/integrationtest/src/test/resources/kotlinFullFeatureTest/pom.xml b/integrationtest/src/test/resources/kotlinFullFeatureTest/pom.xml new file mode 100644 index 0000000000..f481fd6963 --- /dev/null +++ b/integrationtest/src/test/resources/kotlinFullFeatureTest/pom.xml @@ -0,0 +1,186 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + kotlinFullFeatureTest + jar + + + 2.3.0 + x + x + x + x + x + x + x + x + x + x + x + x + + + + + generate-via-compiler-plugin-with-annotation-processor-paths + + false + + + + + maven-resources-plugin + + + filter-kotlin-patterns + generate-sources + + copy-resources + + + \${project.build.directory}/kotlin-sources + + + ../../../../../processor/src/test/java + + **/kotlin/**/*.kt + + + ${additionalExclude0} + ${additionalExclude1} + ${additionalExclude2} + ${additionalExclude3} + ${additionalExclude4} + ${additionalExclude5} + ${additionalExclude6} + ${additionalExclude7} + ${additionalExclude8} + ${additionalExclude9} + ${additionalExclude10} + ${additionalExclude11} + ${additionalExclude12} + ${additionalExclude13} + + + + true + + + + + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + kotlin-compile + compile + + compile + + + \${compiler-source-target-version} + + \${project.build.directory}/kotlin-sources + + + + ${project.groupId} + mapstruct-processor + ${mapstruct.version} + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + + + + default-compile + none + + + default-testCompile + none + + + + + java-compile + compile + + compile + + + + ../../../../../processor/src/test/java + + + **/kotlin/**/*.java + + + **/erroneous/**/*.java + **/*Erroneous*.java + **/*Test.java + **/testutil/**/*.java + ${additionalExclude0} + ${additionalExclude1} + ${additionalExclude2} + ${additionalExclude3} + ${additionalExclude4} + ${additionalExclude5} + ${additionalExclude6} + ${additionalExclude7} + ${additionalExclude8} + ${additionalExclude9} + ${additionalExclude10} + ${additionalExclude11} + ${additionalExclude12} + ${additionalExclude13} + + + + + java-test-compile + test-compile + + testCompile + + + + + + + + + + + + org.jetbrains.kotlin + kotlin-stdlib + + + + diff --git a/integrationtest/src/test/resources/lombokBuilderTest/pom.xml b/integrationtest/src/test/resources/lombokBuilderTest/pom.xml index e96551d6da..5d43efb1d3 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/pom.xml +++ b/integrationtest/src/test/resources/lombokBuilderTest/pom.xml @@ -1,22 +1,9 @@ @@ -38,5 +25,11 @@ lombok compile + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + compile + diff --git a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Address.java b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Address.java index e367a8e086..248587a308 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Address.java +++ b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.lombok; diff --git a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java index 871fd58237..36c71607b6 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java +++ b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.lombok; diff --git a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Person.java b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Person.java index 92a97ec686..fcfaa6f49f 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Person.java +++ b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/Person.java @@ -1,29 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.lombok; import lombok.Builder; import lombok.Getter; -//TODO make MapStruct DefaultBuilderProvider work with custom builder name -//@Builder(builderMethodName = "foo", buildMethodName = "create", builderClassName = "Builder") -@Builder(builderClassName = "Builder") +@Builder(builderMethodName = "foo", buildMethodName = "create", builderClassName = "Builder") @Getter public class Person { private final String name; diff --git a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java index 90443f548d..f5607d8b74 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java +++ b/integrationtest/src/test/resources/lombokBuilderTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.lombok; diff --git a/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java b/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java index 36188efc42..060fb5a990 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java +++ b/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java @@ -1,24 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.lombok; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mapstruct.factory.Mappers; import static org.assertj.core.api.Assertions.assertThat; @@ -28,17 +15,17 @@ * * @author Eric Martineau */ -public class LombokMapperTest { +class LombokMapperTest { @Test - public void testSimpleImmutableBuilderHappyPath() { - PersonDto personDto = PersonMapper.INSTANCE.toDto( Person.builder() + void testSimpleImmutableBuilderHappyPath() { + PersonDto personDto = PersonMapper.INSTANCE.toDto( Person.foo() .age( 33 ) .name( "Bob" ) .address( Address.builder() .addressLine( "Wild Drive" ) .build() ) - .build() ); + .create() ); assertThat( personDto.getAge() ).isEqualTo( 33 ); assertThat( personDto.getName() ).isEqualTo( "Bob" ); assertThat( personDto.getAddress() ).isNotNull(); @@ -46,7 +33,7 @@ public void testSimpleImmutableBuilderHappyPath() { } @Test - public void testLombokToImmutable() { + void testLombokToImmutable() { Person person = PersonMapper.INSTANCE.fromDto( new PersonDto( "Bob", 33, new AddressDto( "Wild Drive" ) ) ); assertThat( person.getAge() ).isEqualTo( 33 ); assertThat( person.getName() ).isEqualTo( "Bob" ); diff --git a/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/PersonMapper.java b/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/PersonMapper.java index 120396af0b..a7185d5011 100644 --- a/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/PersonMapper.java +++ b/integrationtest/src/test/resources/lombokBuilderTest/src/test/java/org/mapstruct/itest/lombok/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.lombok; diff --git a/integrationtest/src/test/resources/lombokModuleTest/pom.xml b/integrationtest/src/test/resources/lombokModuleTest/pom.xml new file mode 100644 index 0000000000..4280b38417 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/pom.xml @@ -0,0 +1,85 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + lombokModuleIntegrationTest + jar + + + 11 + 11 + + + + + org.projectlombok + lombok + compile + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + compile + + + + + + generate-via-compiler-plugin-with-annotation-processor-paths + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + \${compiler-id} + + + ${project.groupId} + mapstruct-processor + ${mapstruct.version} + + + org.projectlombok + lombok + 1.18.38 + + + org.projectlombok + lombok-mapstruct-binding + 0.2.0 + + + + + + org.eclipse.tycho + tycho-compiler-jdt + ${org.eclipse.tycho.compiler-jdt.version} + + + + + + + + diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/main/java/module-info.java b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/module-info.java new file mode 100644 index 0000000000..9bc85bea86 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/module-info.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +module org.example { + requires org.mapstruct; + requires lombok; +} diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/Address.java b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/Address.java new file mode 100644 index 0000000000..f83c6881ce --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/Address.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.lombok; + +public class Address { + private final String addressLine; + + public Address(String addressLine) { + this.addressLine = addressLine; + } + + public String getAddressLine() { + return addressLine; + } +} diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java new file mode 100644 index 0000000000..d6b4f30f88 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/AddressDto.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.lombok; + +public class AddressDto { + + private final String addressLine; + + public AddressDto(String addressLine) { + this.addressLine = addressLine; + } + + public String getAddressLine() { + return addressLine; + } +} diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/Person.java b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/Person.java new file mode 100644 index 0000000000..b6ca47fca1 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/Person.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.lombok; + +public class Person { + private final String name; + private final int age; + private final Address address; + + public Person(String name, int age, Address address) { + this.name = name; + this.age = age; + this.address = address; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public Address getAddress() { + return address; + } +} diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java new file mode 100644 index 0000000000..3223778663 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/PersonDto.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.lombok; + +public class PersonDto { + private final String name; + private final int age; + private final AddressDto address; + + public PersonDto(String name, int age, AddressDto address) { + this.name = name; + this.age = age; + this.address = address; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public AddressDto getAddress() { + return address; + } +} diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/PersonMapper.java b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/PersonMapper.java new file mode 100644 index 0000000000..27184bad27 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/main/java/org/mapstruct/itest/lombok/PersonMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.lombok; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface PersonMapper { + + PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class ); + + Person fromDto(PersonDto personDto); + PersonDto toDto(Person personDto); +} diff --git a/integrationtest/src/test/resources/lombokModuleTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java b/integrationtest/src/test/resources/lombokModuleTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java new file mode 100644 index 0000000000..bdf8f46a57 --- /dev/null +++ b/integrationtest/src/test/resources/lombokModuleTest/src/test/java/org/mapstruct/itest/lombok/LombokMapperTest.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.lombok; + +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for generation of Lombok Builder Mapper implementations + * + * @author Eric Martineau + */ +class LombokMapperTest { + + @Test + void testSimpleImmutableBuilderHappyPath() { + PersonDto personDto = PersonMapper.INSTANCE.toDto( new Person( "Bob", 33, new Address( "Wild Drive" ) ) ); + assertThat( personDto.getAge() ).isEqualTo( 33 ); + assertThat( personDto.getName() ).isEqualTo( "Bob" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "Wild Drive" ); + } + + @Test + void testLombokToImmutable() { + Person person = PersonMapper.INSTANCE.fromDto( new PersonDto( "Bob", 33, new AddressDto( "Wild Drive" ) ) ); + assertThat( person.getAge() ).isEqualTo( 33 ); + assertThat( person.getName() ).isEqualTo( "Bob" ); + assertThat( person.getAddress() ).isNotNull(); + assertThat( person.getAddress().getAddressLine() ).isEqualTo( "Wild Drive" ); + } +} diff --git a/integrationtest/src/test/resources/moduleInfoTest/pom.xml b/integrationtest/src/test/resources/moduleInfoTest/pom.xml new file mode 100644 index 0000000000..4561a1b69e --- /dev/null +++ b/integrationtest/src/test/resources/moduleInfoTest/pom.xml @@ -0,0 +1,24 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + modulesTest + jar + + diff --git a/integrationtest/src/test/resources/moduleInfoTest/src/main/java/module-info.java b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/module-info.java new file mode 100644 index 0000000000..07b4a62b06 --- /dev/null +++ b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/module-info.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +module test.mapstruct { + requires org.mapstruct; + exports org.mapstruct.itest.modules; +} diff --git a/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerDto.java b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerDto.java new file mode 100644 index 0000000000..30ebb32968 --- /dev/null +++ b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.modules; + +/** + * @author Filip Hrisafov + */ +public class CustomerDto { + + private String name; + private String email; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerEntity.java b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerEntity.java new file mode 100644 index 0000000000..a52a887f08 --- /dev/null +++ b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerEntity.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.modules; + +/** + * @author Filip Hrisafov + */ +public class CustomerEntity { + + private String name; + private String mail; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } +} diff --git a/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerMapper.java b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerMapper.java new file mode 100644 index 0000000000..119bffaae8 --- /dev/null +++ b/integrationtest/src/test/resources/moduleInfoTest/src/main/java/org/mapstruct/itest/modules/CustomerMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.modules; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "mail", source = "email") + CustomerEntity fromDto(CustomerDto record); + +} diff --git a/integrationtest/src/test/resources/moduleInfoTest/src/test/java/org/mapstruct/itest/modules/ModulesTest.java b/integrationtest/src/test/resources/moduleInfoTest/src/test/java/org/mapstruct/itest/modules/ModulesTest.java new file mode 100644 index 0000000000..d54c7e6572 --- /dev/null +++ b/integrationtest/src/test/resources/moduleInfoTest/src/test/java/org/mapstruct/itest/modules/ModulesTest.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.modules; + +import org.junit.jupiter.api.Test; +import org.mapstruct.itest.modules.CustomerDto; +import org.mapstruct.itest.modules.CustomerEntity; +import org.mapstruct.itest.modules.CustomerMapper; + +import static org.assertj.core.api.Assertions.assertThat; + +class ModulesTest { + + @Test + void shouldMapRecord() { + CustomerDto dto = new CustomerDto(); + dto.setName( "Kermit" ); + dto.setEmail( "kermit@test.com" ); + CustomerEntity customer = CustomerMapper.INSTANCE.fromDto( dto ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getMail() ).isEqualTo( "kermit@test.com" ); + } +} diff --git a/integrationtest/src/test/resources/namingStrategyTest/pom.xml b/integrationtest/src/test/resources/namingStrategyTest/pom.xml index 55df5f7163..c337167b53 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/pom.xml +++ b/integrationtest/src/test/resources/namingStrategyTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/namingStrategyTest/strategy/pom.xml b/integrationtest/src/test/resources/namingStrategyTest/strategy/pom.xml index 40885abf15..6045742e36 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/strategy/pom.xml +++ b/integrationtest/src/test/resources/namingStrategyTest/strategy/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/namingStrategyTest/strategy/src/main/java/org/mapstruct/itest/naming/CustomAccessorNamingStrategy.java b/integrationtest/src/test/resources/namingStrategyTest/strategy/src/main/java/org/mapstruct/itest/naming/CustomAccessorNamingStrategy.java index 1e3e31b258..eb9d07a246 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/strategy/src/main/java/org/mapstruct/itest/naming/CustomAccessorNamingStrategy.java +++ b/integrationtest/src/test/resources/namingStrategyTest/strategy/src/main/java/org/mapstruct/itest/naming/CustomAccessorNamingStrategy.java @@ -1,30 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.naming; -import java.beans.Introspector; - import javax.lang.model.element.ExecutableElement; import javax.lang.model.type.TypeKind; import org.mapstruct.ap.spi.AccessorNamingStrategy; import org.mapstruct.ap.spi.DefaultAccessorNamingStrategy; +import org.mapstruct.ap.spi.util.IntrospectorUtils; /** * A custom {@link AccessorNamingStrategy} recognizing getters in the form of {@code property()} and setters in the @@ -55,13 +41,14 @@ public boolean isAdderMethod(ExecutableElement method) { @Override public String getPropertyName(ExecutableElement getterOrSetterMethod) { String methodName = getterOrSetterMethod.getSimpleName().toString(); - return Introspector.decapitalize( methodName.startsWith( "with" ) ? methodName.substring( 4 ) : methodName ); + return IntrospectorUtils.decapitalize( + methodName.startsWith( "with" ) ? methodName.substring( 4 ) : methodName ); } @Override public String getElementName(ExecutableElement adderMethod) { String methodName = adderMethod.getSimpleName().toString(); - return Introspector.decapitalize( methodName.substring( 3 ) ); + return IntrospectorUtils.decapitalize( methodName.substring( 3 ) ); } } diff --git a/integrationtest/src/test/resources/namingStrategyTest/usage/pom.xml b/integrationtest/src/test/resources/namingStrategyTest/usage/pom.xml index 637d1810e5..319cefd218 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/usage/pom.xml +++ b/integrationtest/src/test/resources/namingStrategyTest/usage/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayer.java b/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayer.java index 0a5d4fb939..0536f5ee01 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayer.java +++ b/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.naming; diff --git a/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerDto.java b/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerDto.java index c049269827..62e9893ce2 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerDto.java +++ b/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.naming; diff --git a/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerMapper.java b/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerMapper.java index 49363e3475..07dcf00b76 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerMapper.java +++ b/integrationtest/src/test/resources/namingStrategyTest/usage/src/main/java/org/mapstruct/itest/naming/GolfPlayerMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.naming; diff --git a/integrationtest/src/test/resources/namingStrategyTest/usage/src/test/java/org/mapstruct/itest/naming/NamingTest.java b/integrationtest/src/test/resources/namingStrategyTest/usage/src/test/java/org/mapstruct/itest/naming/NamingTest.java index 42d752d455..42cd5084ab 100644 --- a/integrationtest/src/test/resources/namingStrategyTest/usage/src/test/java/org/mapstruct/itest/naming/NamingTest.java +++ b/integrationtest/src/test/resources/namingStrategyTest/usage/src/test/java/org/mapstruct/itest/naming/NamingTest.java @@ -1,39 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.naming; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mapstruct.itest.naming.GolfPlayer; import org.mapstruct.itest.naming.GolfPlayerDto; import org.mapstruct.itest.naming.GolfPlayerMapper; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for using a custom naming strategy. * * @author Gunnar Morling */ -public class NamingTest { +class NamingTest { @Test - public void shouldApplyCustomNamingStrategy() { + void shouldApplyCustomNamingStrategy() { GolfPlayer player = new GolfPlayer() .withName( "Jared" ) .withHandicap( 9.2D ); diff --git a/integrationtest/src/test/resources/pom.xml b/integrationtest/src/test/resources/pom.xml index 55a52e5a18..f4cd0b51de 100644 --- a/integrationtest/src/test/resources/pom.xml +++ b/integrationtest/src/test/resources/pom.xml @@ -1,22 +1,9 @@ ${mapstruct.version} - mapstruct - - - - 1.7.1 + 6.0.3 @@ -82,35 +65,31 @@ - generate-via-processor-plugin + generate-via-compiler-plugin-with-annotation-processor-paths false - org.bsc.maven - maven-processor-plugin - - - process - generate-sources - - process - - - + org.apache.maven.plugins + maven-compiler-plugin - \${project.build.directory}/generated-sources/mapstruct - - org.mapstruct.ap.MappingProcessor - + + \${compiler-id} + + + ${project.groupId} + mapstruct-processor + ${mapstruct.version} + + - ${project.groupId} - mapstruct-processor - ${mapstruct.version} + org.eclipse.tycho + tycho-compiler-jdt + ${org.eclipse.tycho.compiler-jdt.version} @@ -150,15 +129,15 @@ ${project.groupId} - \${mapstruct-artifact-id} + mapstruct ${mapstruct.version} provided - junit - junit + org.junit.jupiter + junit-jupiter test @@ -178,19 +157,6 @@ \${compiler-source-target-version} - - org.apache.maven.plugins - maven-toolchains-plugin - 1.0 - - - - \${toolchain-jdk-version} - \${toolchain-jdk-vendor} - - - - org.apache.maven.plugins maven-enforcer-plugin diff --git a/integrationtest/src/test/resources/protobufBuilderTest/pom.xml b/integrationtest/src/test/resources/protobufBuilderTest/pom.xml new file mode 100644 index 0000000000..c0d8e2a81b --- /dev/null +++ b/integrationtest/src/test/resources/protobufBuilderTest/pom.xml @@ -0,0 +1,69 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + protobufIntegrationTest + jar + + + 1.6.0 + 0.6.1 + + + + + com.google.protobuf + protobuf-java + provided + + + + + + + kr.motd.maven + os-maven-plugin + ${os.mavenplugin.version} + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + ${protobuf.mavenplugin.version} + + + generate-sources + + compile + compile-custom + + + com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} + + grpc-java + io.grpc:protoc-gen-grpc-java:1.47.0:exe:${os.detected.classifier} + + + + + + + + diff --git a/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/AddressDto.java b/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/AddressDto.java new file mode 100644 index 0000000000..0956722de8 --- /dev/null +++ b/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/AddressDto.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.protobuf; + +public class AddressDto { + + private String addressLine; + + public AddressDto() { + + } + + public AddressDto(String addressLine) { + this.addressLine = addressLine; + } + + public String getAddressLine() { + return addressLine; + } + + public void setAddressLine(String addressLine) { + this.addressLine = addressLine; + } +} diff --git a/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/PersonDto.java b/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/PersonDto.java new file mode 100644 index 0000000000..61ee37b391 --- /dev/null +++ b/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/PersonDto.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.protobuf; + +public class PersonDto { + private String name; + private int age; + private AddressDto address; + + public PersonDto() { + } + + public PersonDto(String name, int age, AddressDto address) { + this.name = name; + this.age = age; + this.address = address; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public AddressDto getAddress() { + return address; + } + + public void setAddress(AddressDto address) { + this.address = address; + } +} diff --git a/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/PersonMapper.java b/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/PersonMapper.java new file mode 100644 index 0000000000..b5cdc8575a --- /dev/null +++ b/integrationtest/src/test/resources/protobufBuilderTest/src/main/java/org/mapstruct/itest/protobuf/PersonMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.protobuf; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) // protobuf has a lot of strange additional setters/getters +public interface PersonMapper { + + PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class ); + + PersonProtos.Person fromDto(PersonDto personDto); + PersonDto toDto(PersonProtos.Person personDto); +} diff --git a/integrationtest/src/test/resources/protobufBuilderTest/src/main/proto/Person.proto b/integrationtest/src/test/resources/protobufBuilderTest/src/main/proto/Person.proto new file mode 100644 index 0000000000..209c2220b8 --- /dev/null +++ b/integrationtest/src/test/resources/protobufBuilderTest/src/main/proto/Person.proto @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +syntax = "proto3"; + +package itest.protobuf; + +option java_package = "org.mapstruct.itest.protobuf"; +option java_outer_classname = "PersonProtos"; + +message Person { + string name = 1; + int32 age = 2; + Address address = 3; + + message Address { + string addressLine = 1; + } +} \ No newline at end of file diff --git a/integrationtest/src/test/resources/protobufBuilderTest/src/test/java/org/mapstruct/itest/protobuf/ProtobufMapperTest.java b/integrationtest/src/test/resources/protobufBuilderTest/src/test/java/org/mapstruct/itest/protobuf/ProtobufMapperTest.java new file mode 100644 index 0000000000..ac97eba8b4 --- /dev/null +++ b/integrationtest/src/test/resources/protobufBuilderTest/src/test/java/org/mapstruct/itest/protobuf/ProtobufMapperTest.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.protobuf; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for generation of Protobuf Builder Mapper implementations + * + * @author Christian Bandowski + */ +class ProtobufMapperTest { + + @Test + void testSimpleImmutableBuilderHappyPath() { + PersonDto personDto = PersonMapper.INSTANCE.toDto( PersonProtos.Person.newBuilder() + .setAge( 33 ) + .setName( "Bob" ) + .setAddress( PersonProtos.Person.Address.newBuilder() + .setAddressLine( "Wild Drive" ) + .build() ) + .build() ); + + assertThat( personDto.getAge() ).isEqualTo( 33 ); + assertThat( personDto.getName() ).isEqualTo( "Bob" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "Wild Drive" ); + } + + @Test + void testLombokToImmutable() { + PersonProtos.Person person = PersonMapper.INSTANCE.fromDto( new PersonDto( "Bob", 33, new AddressDto( "Wild Drive" ) ) ); + + assertThat( person.getAge() ).isEqualTo( 33 ); + assertThat( person.getName() ).isEqualTo( "Bob" ); + assertThat( person.getAddress() ).isNotNull(); + assertThat( person.getAddress().getAddressLine() ).isEqualTo( "Wild Drive" ); + } +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/pom.xml b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/pom.xml new file mode 100644 index 0000000000..72df10f62c --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/pom.xml @@ -0,0 +1,22 @@ + + + + 4.0.0 + + + recordsCrossModuleInterfaceTest + org.mapstruct + 1.0.0 + + + records-cross-module-1 + + diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/NestedInterface.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/NestedInterface.java new file mode 100644 index 0000000000..ffa53f88b1 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/NestedInterface.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module1; + +public interface NestedInterface { + String field(); +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/RootInterface.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/RootInterface.java new file mode 100644 index 0000000000..fb23ffe157 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/RootInterface.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module1; + +public interface RootInterface { + NestedInterface nested(); +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/SourceNestedRecord.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/SourceNestedRecord.java new file mode 100644 index 0000000000..6a0ddb86af --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/SourceNestedRecord.java @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module1; + +public record SourceNestedRecord( + String field +) implements NestedInterface { +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/SourceRootRecord.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/SourceRootRecord.java new file mode 100644 index 0000000000..151ad5208d --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-1/src/main/java/org/mapstruct/itest/records/module1/SourceRootRecord.java @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module1; + +public record SourceRootRecord( + SourceNestedRecord nested +) implements RootInterface { +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/pom.xml b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/pom.xml new file mode 100644 index 0000000000..5f42efd18e --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + + recordsCrossModuleInterfaceTest + org.mapstruct + 1.0.0 + + + records-cross-module-2 + + + + + org.mapstruct + records-cross-module-1 + 1.0.0 + + + diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/RecordInterfaceIssueMapper.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/RecordInterfaceIssueMapper.java new file mode 100644 index 0000000000..3efba3ec99 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/RecordInterfaceIssueMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module2; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; +import org.mapstruct.itest.records.module1.SourceRootRecord; + +@Mapper +public interface RecordInterfaceIssueMapper { + + RecordInterfaceIssueMapper INSTANCE = Mappers.getMapper(RecordInterfaceIssueMapper.class); + + TargetRootRecord map(SourceRootRecord source); +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/TargetNestedRecord.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/TargetNestedRecord.java new file mode 100644 index 0000000000..d02a4b58e0 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/TargetNestedRecord.java @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module2; + +public record TargetNestedRecord( + String field +) { +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/TargetRootRecord.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/TargetRootRecord.java new file mode 100644 index 0000000000..09a69f1bf1 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/main/java/org/mapstruct/itest/records/module2/TargetRootRecord.java @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module2; + +public record TargetRootRecord( + TargetNestedRecord nested +) { +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/test/java/org/mapstruct/itest/records/module2/RecordsTest.java b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/test/java/org/mapstruct/itest/records/module2/RecordsTest.java new file mode 100644 index 0000000000..7dc5f3b38d --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/module-2/src/test/java/org/mapstruct/itest/records/module2/RecordsTest.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.module2; + +import org.junit.jupiter.api.Test; +import org.mapstruct.itest.records.module1.SourceNestedRecord; +import org.mapstruct.itest.records.module1.SourceRootRecord; + +import static org.assertj.core.api.Assertions.assertThat; + +class RecordsTest { + + @Test + void shouldMap() { + SourceRootRecord source = new SourceRootRecord( new SourceNestedRecord( "test" ) ); + TargetRootRecord target = RecordInterfaceIssueMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.nested() ).isNotNull(); + assertThat( target.nested().field() ).isEqualTo( "test" ); + } + +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/pom.xml b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/pom.xml new file mode 100644 index 0000000000..120c849dca --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleInterfaceTest/pom.xml @@ -0,0 +1,26 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + recordsCrossModuleInterfaceTest + pom + + + module-1 + module-2 + + diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/api/pom.xml b/integrationtest/src/test/resources/recordsCrossModuleTest/api/pom.xml new file mode 100644 index 0000000000..362f2d3840 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/api/pom.xml @@ -0,0 +1,22 @@ + + + + 4.0.0 + + + recordsCrossModuleTest + org.mapstruct + 1.0.0 + + + records-cross-module-api + + diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/api/src/main/java/org/mapstruct/itest/records/api/CustomerDto.java b/integrationtest/src/test/resources/recordsCrossModuleTest/api/src/main/java/org/mapstruct/itest/records/api/CustomerDto.java new file mode 100644 index 0000000000..344aa79d96 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/api/src/main/java/org/mapstruct/itest/records/api/CustomerDto.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.api; + +/** + * @author Filip Hrisafov + */ +public record CustomerDto(String name, String email) { + +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/pom.xml b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/pom.xml new file mode 100644 index 0000000000..6fc250ed45 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/pom.xml @@ -0,0 +1,30 @@ + + + + 4.0.0 + + + recordsCrossModuleTest + org.mapstruct + 1.0.0 + + + records-cross-module-mapper + + + + + org.mapstruct + records-cross-module-api + 1.0.0 + + + diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/main/java/org/mapstruct/itest/records/mapper/CustomerEntity.java b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/main/java/org/mapstruct/itest/records/mapper/CustomerEntity.java new file mode 100644 index 0000000000..51bcdaa8e1 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/main/java/org/mapstruct/itest/records/mapper/CustomerEntity.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.mapper; + +/** + * @author Filip Hrisafov + */ +public class CustomerEntity { + + private String name; + private String mail; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/main/java/org/mapstruct/itest/records/mapper/CustomerMapper.java b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/main/java/org/mapstruct/itest/records/mapper/CustomerMapper.java new file mode 100644 index 0000000000..7b679a4245 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/main/java/org/mapstruct/itest/records/mapper/CustomerMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; +import org.mapstruct.itest.records.api.CustomerDto; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "mail", source = "email") + CustomerEntity fromRecord(CustomerDto record); + + @InheritInverseConfiguration + CustomerDto toRecord(CustomerEntity entity); + +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/test/java/org/mapstruct/itest/records/mapper/RecordsTest.java b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/test/java/org/mapstruct/itest/records/mapper/RecordsTest.java new file mode 100644 index 0000000000..49c73f2f9c --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/mapper/src/test/java/org/mapstruct/itest/records/mapper/RecordsTest.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.mapper; + +import org.junit.jupiter.api.Test; +import org.mapstruct.itest.records.api.CustomerDto; +import org.mapstruct.itest.records.mapper.CustomerEntity; +import org.mapstruct.itest.records.mapper.CustomerMapper; + +import static org.assertj.core.api.Assertions.assertThat; + +class RecordsTest { + + @Test + void shouldMapRecord() { + CustomerEntity customer = CustomerMapper.INSTANCE.fromRecord( new CustomerDto( "Kermit", "kermit@test.com" ) ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getMail() ).isEqualTo( "kermit@test.com" ); + } + + @Test + void shouldMapIntoRecord() { + CustomerEntity entity = new CustomerEntity(); + entity.setName( "Kermit" ); + entity.setMail( "kermit@test.com" ); + + CustomerDto customer = CustomerMapper.INSTANCE.toRecord( entity ); + + assertThat( customer ).isNotNull(); + assertThat( customer.name() ).isEqualTo( "Kermit" ); + assertThat( customer.email() ).isEqualTo( "kermit@test.com" ); + } + +} diff --git a/integrationtest/src/test/resources/recordsCrossModuleTest/pom.xml b/integrationtest/src/test/resources/recordsCrossModuleTest/pom.xml new file mode 100644 index 0000000000..47c55ea410 --- /dev/null +++ b/integrationtest/src/test/resources/recordsCrossModuleTest/pom.xml @@ -0,0 +1,26 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + recordsCrossModuleTest + pom + + + api + mapper + + diff --git a/integrationtest/src/test/resources/recordsTest/pom.xml b/integrationtest/src/test/resources/recordsTest/pom.xml new file mode 100644 index 0000000000..c74469a7ba --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/pom.xml @@ -0,0 +1,102 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + recordsTest + jar + + + + generate-via-compiler-plugin + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + \${compiler-id} + --enable-preview + + + + org.eclipse.tycho + tycho-compiler-jdt + ${org.eclipse.tycho.compiler-jdt.version} + + + + + + + + ${project.groupId} + mapstruct-processor + ${mapstruct.version} + provided + + + + + debug-forked-javac + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + + true + + --enable-preview + -J-Xdebug + -J-Xnoagent + -J-Djava.compiler=NONE + -J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + 1 + --enable-preview + + + + + + diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Car.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Car.java new file mode 100644 index 0000000000..9332c47dfb --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Car.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class Car { + + private List wheelPositions; + + public List getWheelPositions() { + return wheelPositions; + } + + public void setWheelPositions(List wheelPositions) { + this.wheelPositions = wheelPositions; + } +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CarAndWheelMapper.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CarAndWheelMapper.java new file mode 100644 index 0000000000..cc69ae7605 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CarAndWheelMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface CarAndWheelMapper { + + CarAndWheelMapper INSTANCE = Mappers.getMapper( CarAndWheelMapper.class ); + + default String stringFromWheelPosition(WheelPosition source) { + return source == null ? null : source.getPosition(); + } + + default WheelPosition wheelPositionFromString(String source) { + return source == null ? null : new WheelPosition(source); + } + + CarDto carDtoFromCar(Car source); + + Car carFromCarDto(CarDto source); +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CarDto.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CarDto.java new file mode 100644 index 0000000000..5470550060 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CarDto.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public record CarDto(List wheelPositions) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerDto.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerDto.java new file mode 100644 index 0000000000..69b2547bc3 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerDto.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +/** + * @author Filip Hrisafov + */ +public record CustomerDto(String name, String email) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerEntity.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerEntity.java new file mode 100644 index 0000000000..1663bbac5a --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerEntity.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +/** + * @author Filip Hrisafov + */ +public class CustomerEntity { + + private String name; + private String mail; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerMapper.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerMapper.java new file mode 100644 index 0000000000..addb8c5906 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/CustomerMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "mail", source = "email") + CustomerEntity fromRecord(CustomerDto record); + + @InheritInverseConfiguration + CustomerDto toRecord(CustomerEntity entity); + + @Mapping(target = "value", source = "name") + GenericRecord toValue(CustomerEntity entity); + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Default.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Default.java new file mode 100644 index 0000000000..b845bdd730 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Default.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Filip Hrisafov + */ +@Documented +@Target(ElementType.CONSTRUCTOR) +@Retention(RetentionPolicy.SOURCE) +public @interface Default { +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/GenericRecord.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/GenericRecord.java new file mode 100644 index 0000000000..9a39b59968 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/GenericRecord.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +/** + * @author Filip Hrisafov + */ +public record GenericRecord(T value) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberDto.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberDto.java new file mode 100644 index 0000000000..bf3ce6cd94 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberDto.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +/** + * @author Filip Hrisafov + */ +public record MemberDto(Boolean isActive, Boolean premium) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberEntity.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberEntity.java new file mode 100644 index 0000000000..50a7b1ce00 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberEntity.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +/** + * @author Filip Hrisafov + */ +public class MemberEntity { + + private Boolean isActive; + private Boolean premium; + + public Boolean getIsActive() { + return isActive; + } + + public void setIsActive(Boolean active) { + isActive = active; + } + + public Boolean getPremium() { + return premium; + } + + public void setPremium(Boolean premium) { + this.premium = premium; + } +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberMapper.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberMapper.java new file mode 100644 index 0000000000..3460aeed69 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/MemberMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface MemberMapper { + + MemberMapper INSTANCE = Mappers.getMapper( MemberMapper.class ); + + MemberEntity fromRecord(MemberDto record); + + MemberDto toRecord(MemberEntity entity); + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Task.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Task.java new file mode 100644 index 0000000000..3f990fc89a --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/Task.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import java.util.List; + +/** + * @author Oliver Erhart + */ +public record Task( String id, Long number ) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/TaskDto.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/TaskDto.java new file mode 100644 index 0000000000..1ba6eb2be9 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/TaskDto.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import java.util.List; + +/** + * @author Oliver Erhart + */ +public record TaskDto(String id, Long number) { + + @Default + TaskDto(String id) { + this( id, 1L ); + } + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/TaskMapper.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/TaskMapper.java new file mode 100644 index 0000000000..8d9da767cd --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/TaskMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Oliver Erhart + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface TaskMapper { + + TaskMapper INSTANCE = Mappers.getMapper( TaskMapper.class ); + + TaskDto toRecord(Task source); + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/WheelPosition.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/WheelPosition.java new file mode 100644 index 0000000000..fe8016ddbf --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/WheelPosition.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +/** + * @author Filip Hrisafov + */ +public class WheelPosition { + + private final String position; + + public WheelPosition(String position) { + this.position = position; + } + + public String getPosition() { + return position; + } +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/Address.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/Address.java new file mode 100644 index 0000000000..fb857e90ca --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/Address.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.nested; + +/** + * @author Filip Hrisafov + */ +public record Address(String street, String city) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProvider.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProvider.java new file mode 100644 index 0000000000..a0ce13c0ba --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProvider.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.nested; + +/** + * @author Filip Hrisafov + */ +public record CareProvider(String externalId, Address address) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProviderDto.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProviderDto.java new file mode 100644 index 0000000000..d7ce7229e9 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProviderDto.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.nested; + +/** + * @author Filip Hrisafov + */ +public record CareProviderDto(String id, String street, String city) { + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProviderMapper.java b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProviderMapper.java new file mode 100644 index 0000000000..89ed688976 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/main/java/org/mapstruct/itest/records/nested/CareProviderMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.nested; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface CareProviderMapper { + + CareProviderMapper INSTANCE = Mappers.getMapper( CareProviderMapper.class ); + + @Mapping(target = "id", source = "externalId") + @Mapping(target = "street", source = "address.street") + @Mapping(target = "city", source = "address.city") + CareProviderDto map(CareProvider source); +} diff --git a/integrationtest/src/test/resources/recordsTest/src/test/java/org/mapstruct/itest/records/RecordsTest.java b/integrationtest/src/test/resources/recordsTest/src/test/java/org/mapstruct/itest/records/RecordsTest.java new file mode 100644 index 0000000000..0960c92a45 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/test/java/org/mapstruct/itest/records/RecordsTest.java @@ -0,0 +1,98 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; +import org.mapstruct.itest.records.CustomerDto; +import org.mapstruct.itest.records.CustomerEntity; +import org.mapstruct.itest.records.CustomerMapper; + +import static org.assertj.core.api.Assertions.assertThat; + +class RecordsTest { + + @Test + void shouldMapRecord() { + CustomerEntity customer = CustomerMapper.INSTANCE.fromRecord( new CustomerDto( "Kermit", "kermit@test.com" ) ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getMail() ).isEqualTo( "kermit@test.com" ); + } + + @Test + void shouldMapIntoRecord() { + CustomerEntity entity = new CustomerEntity(); + entity.setName( "Kermit" ); + entity.setMail( "kermit@test.com" ); + + CustomerDto customer = CustomerMapper.INSTANCE.toRecord( entity ); + + assertThat( customer ).isNotNull(); + assertThat( customer.name() ).isEqualTo( "Kermit" ); + assertThat( customer.email() ).isEqualTo( "kermit@test.com" ); + } + + @Test + void shouldMapIntoGenericRecord() { + CustomerEntity entity = new CustomerEntity(); + entity.setName( "Kermit" ); + entity.setMail( "kermit@test.com" ); + + GenericRecord value = CustomerMapper.INSTANCE.toValue( entity ); + + assertThat( value ).isNotNull(); + assertThat( value.value() ).isEqualTo( "Kermit" ); + } + + @Test + void shouldMapIntoRecordWithList() { + Car car = new Car(); + car.setWheelPositions( Arrays.asList( new WheelPosition( "left" ) ) ); + + CarDto carDto = CarAndWheelMapper.INSTANCE.carDtoFromCar(car); + + assertThat( carDto ).isNotNull(); + assertThat( carDto.wheelPositions() ) + .containsExactly( "left" ); + } + + @Test + void shouldMapMemberRecord() { + MemberEntity member = MemberMapper.INSTANCE.fromRecord( new MemberDto( true, false ) ); + + assertThat( member ).isNotNull(); + assertThat( member.getIsActive() ).isTrue(); + assertThat( member.getPremium() ).isFalse(); + } + + @Test + void shouldMapIntoMemberRecord() { + MemberEntity entity = new MemberEntity(); + entity.setIsActive( false ); + entity.setPremium( true ); + + MemberDto value = MemberMapper.INSTANCE.toRecord( entity ); + + assertThat( value ).isNotNull(); + assertThat( value.isActive() ).isFalse(); + assertThat( value.premium() ).isTrue(); + } + + @Test + void shouldUseDefaultConstructor() { + Task entity = new Task( "some-id", 1000L ); + + TaskDto value = TaskMapper.INSTANCE.toRecord( entity ); + + assertThat( value ).isNotNull(); + assertThat( value.id() ).isEqualTo( "some-id" ); + assertThat( value.number() ).isEqualTo( 1L ); + } + +} diff --git a/integrationtest/src/test/resources/recordsTest/src/test/java/org/mapstruct/itest/records/nested/NestedRecordsTest.java b/integrationtest/src/test/resources/recordsTest/src/test/java/org/mapstruct/itest/records/nested/NestedRecordsTest.java new file mode 100644 index 0000000000..92f074e382 --- /dev/null +++ b/integrationtest/src/test/resources/recordsTest/src/test/java/org/mapstruct/itest/records/nested/NestedRecordsTest.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.records.nested; + +import java.util.Arrays; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class NestedRecordsTest { + + @Test + void shouldMapRecord() { + CareProvider source = new CareProvider( "kermit", new Address( "Sesame Street", "New York" ) ); + CareProviderDto target = CareProviderMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.id() ).isEqualTo( "kermit" ); + assertThat( target.street() ).isEqualTo( "Sesame Street" ); + assertThat( target.city() ).isEqualTo( "New York" ); + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/pom.xml b/integrationtest/src/test/resources/sealedSubclassTest/pom.xml new file mode 100644 index 0000000000..0706425e01 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/pom.xml @@ -0,0 +1,102 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + sealedSubclassTest + jar + + + + generate-via-compiler-plugin + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + \${compiler-id} + --enable-preview + + + + org.eclipse.tycho + tycho-compiler-jdt + ${org.eclipse.tycho.compiler-jdt.version} + + + + + + + + ${project.groupId} + mapstruct-processor + ${mapstruct.version} + provided + + + + + debug-forked-javac + + false + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + default-compile + + true + + --enable-preview + -J-Xdebug + -J-Xnoagent + -J-Djava.compiler=NONE + -J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 + + + + + + + + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + 1 + --enable-preview + + + + + + diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Bike.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Bike.java new file mode 100644 index 0000000000..5b68f52e64 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Bike.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class Bike extends Vehicle { + private int numberOfGears; + + public int getNumberOfGears() { + return numberOfGears; + } + + public void setNumberOfGears(int numberOfGears) { + this.numberOfGears = numberOfGears; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/BikeDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/BikeDto.java new file mode 100644 index 0000000000..d51e95633b --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/BikeDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class BikeDto extends VehicleDto { + private int numberOfGears; + + public int getNumberOfGears() { + return numberOfGears; + } + + public void setNumberOfGears(int numberOfGears) { + this.numberOfGears = numberOfGears; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Car.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Car.java new file mode 100644 index 0000000000..0ed238e2a5 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Car.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class Car extends Vehicle { + private boolean manual; + + public boolean isManual() { + return manual; + } + + public void setManual(boolean manual) { + this.manual = manual; + } + +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/CarDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/CarDto.java new file mode 100644 index 0000000000..800bd23d39 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/CarDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class CarDto extends VehicleDto { + private boolean manual; + + public boolean isManual() { + return manual; + } + + public void setManual(boolean manual) { + this.manual = manual; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Davidson.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Davidson.java new file mode 100644 index 0000000000..e883c14be3 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Davidson.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class Davidson extends Motor { + private int numberOfExhausts; + + public int getNumberOfExhausts() { + return numberOfExhausts; + } + + public void setNumberOfExhausts(int numberOfExhausts) { + this.numberOfExhausts = numberOfExhausts; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/DavidsonDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/DavidsonDto.java new file mode 100644 index 0000000000..e975226e3e --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/DavidsonDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class DavidsonDto extends MotorDto { + private int numberOfExhausts; + + public int getNumberOfExhausts() { + return numberOfExhausts; + } + + public void setNumberOfExhausts(int numberOfExhausts) { + this.numberOfExhausts = numberOfExhausts; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Harley.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Harley.java new file mode 100644 index 0000000000..87a48034c6 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Harley.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class Harley extends Motor { + private int engineDb; + + public int getEngineDb() { + return engineDb; + } + + public void setEngineDb(int engineDb) { + this.engineDb = engineDb; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/HarleyDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/HarleyDto.java new file mode 100644 index 0000000000..2090ee7450 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/HarleyDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public final class HarleyDto extends MotorDto { + private int engineDb; + + public int getEngineDb() { + return engineDb; + } + + public void setEngineDb(int engineDb) { + this.engineDb = engineDb; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Motor.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Motor.java new file mode 100644 index 0000000000..fcd5f4e4dc --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Motor.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public sealed abstract class Motor extends Vehicle permits Harley, Davidson { + private int cc; + + public int getCc() { + return cc; + } + + public void setCc(int cc) { + this.cc = cc; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/MotorDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/MotorDto.java new file mode 100644 index 0000000000..bd74eb9296 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/MotorDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public sealed abstract class MotorDto extends VehicleDto permits HarleyDto, DavidsonDto { + private int cc; + + public int getCc() { + return cc; + } + + public void setCc(int cc) { + this.cc = cc; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/SealedSubclassMapper.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/SealedSubclassMapper.java new file mode 100644 index 0000000000..b37f623686 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/SealedSubclassMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SubclassMapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SealedSubclassMapper { + SealedSubclassMapper INSTANCE = Mappers.getMapper( SealedSubclassMapper.class ); + + VehicleCollectionDto map(VehicleCollection vehicles); + + @SubclassMapping( source = Car.class, target = CarDto.class ) + @SubclassMapping( source = Bike.class, target = BikeDto.class ) + @SubclassMapping( source = Harley.class, target = HarleyDto.class ) + @SubclassMapping( source = Davidson.class, target = DavidsonDto.class ) + @Mapping( source = "vehicleManufacturingCompany", target = "maker") + VehicleDto map(Vehicle vehicle); + + VehicleCollection mapInverse(VehicleCollectionDto vehicles); + + @InheritInverseConfiguration + Vehicle mapInverse(VehicleDto dto); +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Vehicle.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Vehicle.java new file mode 100644 index 0000000000..2a4e7560f6 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/Vehicle.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public abstract sealed class Vehicle permits Bike, Car, Motor { + private String name; + private String vehicleManufacturingCompany; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVehicleManufacturingCompany() { + return vehicleManufacturingCompany; + } + + public void setVehicleManufacturingCompany(String vehicleManufacturingCompany) { + this.vehicleManufacturingCompany = vehicleManufacturingCompany; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleCollection.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleCollection.java new file mode 100644 index 0000000000..1ada92a298 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleCollection.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +import java.util.ArrayList; +import java.util.Collection; + +public class VehicleCollection { + private Collection vehicles = new ArrayList<>(); + + public Collection getVehicles() { + return vehicles; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleCollectionDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleCollectionDto.java new file mode 100644 index 0000000000..0cae412177 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleCollectionDto.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +import java.util.ArrayList; +import java.util.Collection; + +public class VehicleCollectionDto { + private Collection vehicles = new ArrayList<>(); + + public Collection getVehicles() { + return vehicles; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleDto.java b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleDto.java new file mode 100644 index 0000000000..8c50bdcad9 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/main/java/org/mapstruct/itest/sealedsubclass/VehicleDto.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +public abstract sealed class VehicleDto permits CarDto, BikeDto, MotorDto { + private String name; + private String maker; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMaker() { + return maker; + } + + public void setMaker(String maker) { + this.maker = maker; + } +} diff --git a/integrationtest/src/test/resources/sealedSubclassTest/src/test/java/org/mapstruct/itest/sealedsubclass/SealedSubclassTest.java b/integrationtest/src/test/resources/sealedSubclassTest/src/test/java/org/mapstruct/itest/sealedsubclass/SealedSubclassTest.java new file mode 100644 index 0000000000..4fc08b4a33 --- /dev/null +++ b/integrationtest/src/test/resources/sealedSubclassTest/src/test/java/org/mapstruct/itest/sealedsubclass/SealedSubclassTest.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.sealedsubclass; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class SealedSubclassTest { + + @Test + void mappingIsDoneUsingSubclassMapping() { + VehicleCollection vehicles = new VehicleCollection(); + vehicles.getVehicles().add( new Car() ); + vehicles.getVehicles().add( new Bike() ); + vehicles.getVehicles().add( new Harley() ); + vehicles.getVehicles().add( new Davidson() ); + + VehicleCollectionDto result = SealedSubclassMapper.INSTANCE.map( vehicles ); + + assertThat( result.getVehicles() ).doesNotContainNull(); + assertThat( result.getVehicles() ) // remove generic so that test works. + .extracting( vehicle -> (Class) vehicle.getClass() ) + .containsExactly( CarDto.class, BikeDto.class, HarleyDto.class, DavidsonDto.class ); + } + + @Test + void inverseMappingIsDoneUsingSubclassMapping() { + VehicleCollectionDto vehicles = new VehicleCollectionDto(); + vehicles.getVehicles().add( new CarDto() ); + vehicles.getVehicles().add( new BikeDto() ); + vehicles.getVehicles().add( new HarleyDto() ); + vehicles.getVehicles().add( new DavidsonDto() ); + + VehicleCollection result = SealedSubclassMapper.INSTANCE.mapInverse( vehicles ); + + assertThat( result.getVehicles() ).doesNotContainNull(); + assertThat( result.getVehicles() ) // remove generic so that test works. + .extracting( vehicle -> (Class) vehicle.getClass() ) + .containsExactly( Car.class, Bike.class, Harley.class, Davidson.class ); + } + + @Test + void subclassMappingInheritsInverseMapping() { + VehicleCollectionDto vehiclesDto = new VehicleCollectionDto(); + CarDto carDto = new CarDto(); + carDto.setMaker( "BenZ" ); + vehiclesDto.getVehicles().add( carDto ); + + VehicleCollection result = SealedSubclassMapper.INSTANCE.mapInverse( vehiclesDto ); + + assertThat( result.getVehicles() ) + .extracting( Vehicle::getVehicleManufacturingCompany ) + .containsExactly( "BenZ" ); + } +} diff --git a/integrationtest/src/test/resources/simpleTest/pom.xml b/integrationtest/src/test/resources/simpleTest/pom.xml index 8e26a174af..1bcfe99dcb 100644 --- a/integrationtest/src/test/resources/simpleTest/pom.xml +++ b/integrationtest/src/test/resources/simpleTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/BaseType.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/BaseType.java index 3c0c0671f2..1613106a38 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/BaseType.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/BaseType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/ReferencedCustomMapper.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/ReferencedCustomMapper.java index 4eb1887d61..85d551f091 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/ReferencedCustomMapper.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/ReferencedCustomMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeOtherType.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeOtherType.java index 252372e105..cfa55535d9 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeOtherType.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeOtherType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeType.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeType.java index b43354a7b7..2bf7d3454a 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeType.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SomeType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Source.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Source.java index d4fdd01386..48093144cb 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Source.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetAbstractMapper.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetAbstractMapper.java index 51d4254047..dd893384f7 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetAbstractMapper.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetAbstractMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; @@ -29,9 +16,9 @@ public abstract class SourceTargetAbstractMapper { public static SourceTargetAbstractMapper INSTANCE = Mappers.getMapper( SourceTargetAbstractMapper.class ); @Mappings({ - @Mapping(source = "qax", target = "baz"), - @Mapping(source = "baz", target = "qax"), - @Mapping(source = "forNested.value", target = "fromNested") + @Mapping(target = "baz", source = "qax"), + @Mapping(target = "qax", source = "baz"), + @Mapping(target = "fromNested", source = "forNested.value") }) public abstract Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetMapper.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetMapper.java index 5db7a10eef..99f93dab7b 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/SourceTargetMapper.java @@ -1,27 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; +import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.Mappings; -import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.factory.Mappers; @Mapper(uses = ReferencedCustomMapper.class) @@ -30,9 +17,9 @@ public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mappings({ - @Mapping(source = "qax", target = "baz"), - @Mapping(source = "baz", target = "qax"), - @Mapping(source = "forNested.value", target = "fromNested") + @Mapping(target = "baz", source = "qax"), + @Mapping(target = "qax", source = "baz"), + @Mapping(target = "fromNested", source = "forNested.value") }) Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Target.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Target.java index 4bd4aab266..f9bd8af76b 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Target.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/Target.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; import java.util.List; + import org.mapstruct.itest.simple.SomeType; public class Target { diff --git a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/YetAnotherType.java b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/YetAnotherType.java index 786b154cae..c79d55aef7 100644 --- a/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/YetAnotherType.java +++ b/integrationtest/src/test/resources/simpleTest/src/main/java/org/mapstruct/itest/simple/YetAnotherType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; diff --git a/integrationtest/src/test/resources/simpleTest/src/test/java/org/mapstruct/itest/simple/ConversionTest.java b/integrationtest/src/test/resources/simpleTest/src/test/java/org/mapstruct/itest/simple/ConversionTest.java index a2aff58a7a..e248e3a1ad 100644 --- a/integrationtest/src/test/resources/simpleTest/src/test/java/org/mapstruct/itest/simple/ConversionTest.java +++ b/integrationtest/src/test/resources/simpleTest/src/test/java/org/mapstruct/itest/simple/ConversionTest.java @@ -1,34 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.simple; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mapstruct.itest.simple.Source; import org.mapstruct.itest.simple.SourceTargetMapper; import org.mapstruct.itest.simple.Target; -public class ConversionTest { +import static org.assertj.core.api.Assertions.assertThat; + +class ConversionTest { @Test - public void shouldApplyConversions() { + void shouldApplyConversions() { Source source = new Source(); source.setFoo( 42 ); source.setBar( 23L ); @@ -43,18 +30,18 @@ public void shouldApplyConversions() { } @Test - public void shouldHandleNulls() { + void shouldHandleNulls() { Source source = new Source(); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); assertThat( target ).isNotNull(); assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 1 ) ); - assertThat( target.getBar() ).isEqualTo( 0 ); + assertThat( target.getBar() ).isZero(); assertThat( target.getZip() ).isEqualTo( "0" ); } @Test - public void shouldApplyConversionsToMappedProperties() { + void shouldApplyConversionsToMappedProperties() { Source source = new Source(); source.setQax( 42 ); source.setBaz( 23L ); @@ -67,7 +54,7 @@ public void shouldApplyConversionsToMappedProperties() { } @Test - public void shouldApplyConversionsForReverseMapping() { + void shouldApplyConversionsForReverseMapping() { Target target = new Target(); target.setFoo( 42L ); target.setBar( 23 ); @@ -82,7 +69,7 @@ public void shouldApplyConversionsForReverseMapping() { } @Test - public void shouldApplyConversionsToMappedPropertiesForReverseMapping() { + void shouldApplyConversionsToMappedPropertiesForReverseMapping() { Target target = new Target(); target.setQax( 42 ); target.setBaz( 23L ); @@ -95,7 +82,7 @@ public void shouldApplyConversionsToMappedPropertiesForReverseMapping() { } @Test - public void shouldWorkWithAbstractClass() { + void shouldWorkWithAbstractClass() { Source source = new Source(); source.setFoo( 42 ); source.setBar( 23L ); diff --git a/integrationtest/src/test/resources/springTest/pom.xml b/integrationtest/src/test/resources/springTest/pom.xml index 2ff4606245..e4210c0cba 100644 --- a/integrationtest/src/test/resources/springTest/pom.xml +++ b/integrationtest/src/test/resources/springTest/pom.xml @@ -1,22 +1,9 @@ @@ -31,6 +18,10 @@ springTest jar + + + ${org.junit6.jupiter.version} + diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java index 7bd273c01a..fbb900205b 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/DecoratedSourceTargetMapper.java @@ -1,28 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; -import org.mapstruct.Mapper; import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.spring.other.DateMapper; -@Mapper( componentModel = "spring", uses = DateMapper.class ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, uses = DateMapper.class ) @DecoratedWith( SourceTargetMapperDecorator.class ) public interface DecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java index 4261603ebf..c270594e2a 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondDecoratedSourceTargetMapper.java @@ -1,28 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; -import org.mapstruct.Mapper; import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.spring.other.DateMapper; -@Mapper( componentModel = "spring", uses = DateMapper.class ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, uses = DateMapper.class ) @DecoratedWith( SecondSourceTargetMapperDecorator.class ) public interface SecondDecoratedSourceTargetMapper { diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondSourceTargetMapperDecorator.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondSourceTargetMapperDecorator.java index 3ee87d5dbb..3d710102e3 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondSourceTargetMapperDecorator.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SecondSourceTargetMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Source.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Source.java index ba7f2922ba..b1d1a2850f 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Source.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java index 8b150fb6f7..e6d6b46339 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapper.java @@ -1,27 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.itest.spring.other.DateMapper; -@Mapper(componentModel = "spring", uses = DateMapper.class) +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = DateMapper.class) public interface SourceTargetMapper { Target sourceToTarget(Source source); diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java index e32a69d14c..cb487f52cc 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/SourceTargetMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Target.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Target.java index 2eec511ee3..762c778001 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Target.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; diff --git a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/other/DateMapper.java b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/other/DateMapper.java index 1ccd989480..bb9685e6cb 100644 --- a/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/other/DateMapper.java +++ b/integrationtest/src/test/resources/springTest/src/main/java/org/mapstruct/itest/spring/other/DateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring.other; diff --git a/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java b/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java index b102383bf1..c0f3de4ce2 100644 --- a/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java +++ b/integrationtest/src/test/resources/springTest/src/test/java/org/mapstruct/itest/spring/SpringBasedMapperTest.java @@ -1,31 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.spring; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.mapstruct.itest.spring.SpringBasedMapperTest.SpringTestConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.junit.jupiter.SpringExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -35,8 +22,8 @@ * @author Andreas Gudian */ @ContextConfiguration(classes = SpringTestConfig.class) -@RunWith(SpringJUnit4ClassRunner.class) -public class SpringBasedMapperTest { +@ExtendWith(SpringExtension.class) +class SpringBasedMapperTest { @Configuration @ComponentScan(basePackageClasses = SpringBasedMapperTest.class) @@ -53,7 +40,7 @@ public static class SpringTestConfig { private SecondDecoratedSourceTargetMapper secondDecoratedMapper; @Test - public void shouldInjectSpringBasedMapper() { + void shouldInjectSpringBasedMapper() { Source source = new Source(); Target target = mapper.sourceToTarget( source ); @@ -64,7 +51,7 @@ public void shouldInjectSpringBasedMapper() { } @Test - public void shouldInjectDecorator() { + void shouldInjectDecorator() { Source source = new Source(); Target target = decoratedMapper.sourceToTarget( source ); @@ -81,7 +68,7 @@ public void shouldInjectDecorator() { } @Test - public void shouldInjectSecondDecorator() { + void shouldInjectSecondDecorator() { Source source = new Source(); Target target = secondDecoratedMapper.sourceToTarget( source ); diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/generator/pom.xml b/integrationtest/src/test/resources/superTypeGenerationTest/generator/pom.xml index 9e72814831..f122047093 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/generator/pom.xml +++ b/integrationtest/src/test/resources/superTypeGenerationTest/generator/pom.xml @@ -1,3 +1,10 @@ + 4.0.0 @@ -14,8 +21,8 @@ - junit - junit + org.junit.jupiter + junit-jupiter test @@ -25,10 +32,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 - 1.6 - 1.6 -proc:none diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/BaseGenerationProcessor.java b/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/BaseGenerationProcessor.java index b5b98791ac..1147d78083 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/BaseGenerationProcessor.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/BaseGenerationProcessor.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration; import java.io.IOException; import java.io.Writer; import java.util.Set; - import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/GenBase.java b/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/GenBase.java index ac796f1a42..b5bada8d14 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/GenBase.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/supertypegeneration/GenBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration; diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor index dd8828a3b4..ac02411c1c 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/integrationtest/src/test/resources/superTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1,17 +1,4 @@ -# Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) -# and/or other contributors as indicated by the @authors tag. See the -# copyright.txt file in the distribution for a full listing of all -# contributors. +# Copyright MapStruct Authors. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 org.mapstruct.itest.supertypegeneration.BaseGenerationProcessor \ No newline at end of file diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/pom.xml b/integrationtest/src/test/resources/superTypeGenerationTest/pom.xml index 45c830997d..e522d12b5b 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/pom.xml +++ b/integrationtest/src/test/resources/superTypeGenerationTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/usage/pom.xml b/integrationtest/src/test/resources/superTypeGenerationTest/usage/pom.xml index 3f2d54ec6c..4c5e4611f0 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/usage/pom.xml +++ b/integrationtest/src/test/resources/superTypeGenerationTest/usage/pom.xml @@ -1,3 +1,10 @@ + 4.0.0 @@ -14,9 +21,8 @@ - junit - junit - 4.12 + org.junit.jupiter + junit-jupiter test @@ -32,10 +38,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 - 1.6 - 1.6 -XprintProcessorInfo -XprintRounds diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/AnotherOrderMapper.java b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/AnotherOrderMapper.java index dcf27ff555..09abaf5615 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/AnotherOrderMapper.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/AnotherOrderMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration.usage; diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/Order.java b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/Order.java index d1161c7155..ae2315bb19 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/Order.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/Order.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration.usage; diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderDto.java b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderDto.java index 43e1068333..f70224b753 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderDto.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration.usage; diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderMapper.java b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderMapper.java index 5c018e3e29..b3d6325d74 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderMapper.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/supertypegeneration/usage/OrderMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration.usage; diff --git a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/supertypegeneration/usage/GeneratedBasesTest.java b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/supertypegeneration/usage/GeneratedBasesTest.java index b5fbdfc172..d0c76874ae 100644 --- a/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/supertypegeneration/usage/GeneratedBasesTest.java +++ b/integrationtest/src/test/resources/superTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/supertypegeneration/usage/GeneratedBasesTest.java @@ -1,40 +1,27 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.supertypegeneration.usage; -import static org.junit.Assert.assertEquals; - -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mapstruct.itest.supertypegeneration.usage.Order; import org.mapstruct.itest.supertypegeneration.usage.OrderDto; import org.mapstruct.itest.supertypegeneration.usage.OrderMapper; +import static org.junit.jupiter.api.Assertions.assertEquals; + /** * Integration test for using MapStruct with another annotation processor that generates super-types of mapping source * and target types. * * @author Gunnar Morling */ -public class GeneratedBasesTest { +class GeneratedBasesTest { @Test - public void considersPropertiesOnGeneratedSourceAndTargetTypes() { + void considersPropertiesOnGeneratedSourceAndTargetTypes() { Order order = new Order(); order.setItem( "my item" ); order.setBaseName2( "my base name 2" ); diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml index 589af8215b..89bd9c2d2f 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/pom.xml @@ -1,3 +1,10 @@ + 4.0.0 @@ -14,8 +21,8 @@ - junit - junit + org.junit.jupiter + junit-jupiter test @@ -25,10 +32,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 - 1.6 - 1.6 -proc:none diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java index e4d27a885d..1880055ba2 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/targettypegeneration/DtoGenerationProcessor.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.targettypegeneration; import java.io.IOException; import java.io.Writer; import java.util.Set; - import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor index 1bd0775000..732c6b2124 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1,17 +1,4 @@ -# Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) -# and/or other contributors as indicated by the @authors tag. See the -# copyright.txt file in the distribution for a full listing of all -# contributors. +# Copyright MapStruct Authors. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 org.mapstruct.itest.targettypegeneration.DtoGenerationProcessor diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml b/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml index 5f77262044..ba19d31a71 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/pom.xml @@ -1,22 +1,9 @@ diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml index 520576dad5..0726580592 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/pom.xml @@ -1,3 +1,10 @@ + 4.0.0 @@ -14,9 +21,8 @@ - junit - junit - 4.12 + org.junit.jupiter + junit-jupiter test @@ -32,10 +38,7 @@ org.apache.maven.plugins maven-compiler-plugin - 3.1 - 1.6 - 1.6 -XprintProcessorInfo -XprintRounds diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java index c6a4961124..9c5114675f 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/Order.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.targettypegeneration.usage; diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java index cb842c60f9..45f8c223f9 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/targettypegeneration/usage/OrderMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.targettypegeneration.usage; diff --git a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java index 724754958d..b2e30a4797 100644 --- a/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java +++ b/integrationtest/src/test/resources/targetTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/targettypegeneration/usage/GeneratedTargetTypeTest.java @@ -1,26 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.itest.targettypegeneration.usage; -import static org.junit.Assert.assertEquals; +import org.junit.jupiter.api.Test; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * Integration test for using MapStruct with another annotation processor that generates the target type of a mapping @@ -28,10 +15,10 @@ * * @author Gunnar Morling */ -public class GeneratedTargetTypeTest { +class GeneratedTargetTypeTest { @Test - public void considersPropertiesOnGeneratedSourceAndTargetTypes() { + void considersPropertiesOnGeneratedSourceAndTargetTypes() { Order order = new Order(); order.setItem( "my item" ); diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/generator/pom.xml b/integrationtest/src/test/resources/usesTypeGenerationTest/generator/pom.xml new file mode 100644 index 0000000000..24d3436533 --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/generator/pom.xml @@ -0,0 +1,43 @@ + + + 4.0.0 + + + org.mapstruct.itest + itest-usestypegeneration-aggregator + 1.0.0 + ../pom.xml + + + itest-usestypegeneration-generator + jar + + + + org.junit.jupiter + junit-jupiter + test + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -proc:none + + + + + + diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/usestypegeneration/UsesTypeGenerationProcessor.java b/integrationtest/src/test/resources/usesTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/usestypegeneration/UsesTypeGenerationProcessor.java new file mode 100644 index 0000000000..48b0609d9d --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/generator/src/main/java/org/mapstruct/itest/usestypegeneration/UsesTypeGenerationProcessor.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.usestypegeneration; + +import java.io.IOException; +import java.io.Writer; +import java.util.Set; +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.TypeElement; +import javax.tools.JavaFileObject; + +/** + * Generate conversion uses. + * + * @author Filip Hrisafov + * + */ +@SupportedAnnotationTypes("*") +public class UsesTypeGenerationProcessor extends AbstractProcessor { + + private boolean hasRun = false; + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if ( !hasRun ) { + try { + JavaFileObject dto = processingEnv.getFiler().createSourceFile( "org.mapstruct.itest.usestypegeneration.usage.StringUtils" ); + Writer writer = dto.openWriter(); + + writer.append( "package org.mapstruct.itest.usestypegeneration.usage;" ); + writer.append( "\n" ); + writer.append( "public class StringUtils {" ); + writer.append( "\n" ); + writer.append( " public static String upperCase(String string) {" ); + writer.append( "\n" ); + writer.append( " return string == null ? null : string.toUpperCase();" ); + writer.append( "\n" ); + writer.append( " }" ); + writer.append( "\n" ); + writer.append( "}" ); + + writer.flush(); + writer.close(); + } + catch (IOException e) { + throw new RuntimeException( e ); + } + + hasRun = true; + } + + return false; + } +} diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/integrationtest/src/test/resources/usesTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor new file mode 100644 index 0000000000..57be8919b5 --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/generator/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -0,0 +1,4 @@ +# Copyright MapStruct Authors. +# +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 +org.mapstruct.itest.usestypegeneration.UsesTypeGenerationProcessor diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/pom.xml b/integrationtest/src/test/resources/usesTypeGenerationTest/pom.xml new file mode 100644 index 0000000000..7c0d555eaa --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/pom.xml @@ -0,0 +1,27 @@ + + + + 4.0.0 + + + org.mapstruct + mapstruct-it-parent + 1.0.0 + ../pom.xml + + + org.mapstruct.itest + itest-usestypegeneration-aggregator + pom + + + generator + usage + + diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/usage/pom.xml b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/pom.xml new file mode 100644 index 0000000000..d7154c6246 --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/pom.xml @@ -0,0 +1,51 @@ + + + 4.0.0 + + + org.mapstruct.itest + itest-usestypegeneration-aggregator + 1.0.0 + ../pom.xml + + + itest-usestypegeneration-usage + jar + + + + org.junit.jupiter + junit-jupiter + test + + + org.mapstruct.itest + itest-usestypegeneration-generator + 1.0.0 + provided + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + -XprintProcessorInfo + -XprintRounds + + -proc:none + + + + + diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/Order.java b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/Order.java new file mode 100644 index 0000000000..4d5a102aed --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/Order.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.usestypegeneration.usage; + +/** + * @author Filip Hrisafov + */ +public class Order { + + private String item; + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } +} diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/OrderDto.java b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/OrderDto.java new file mode 100644 index 0000000000..69951da5b2 --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/OrderDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.usestypegeneration.usage; + +/** + * @author Filip Hrisafov + */ +public class OrderDto { + + private String item; + + public String getItem() { + return item; + } + + public void setItem(String item) { + this.item = item; + } +} diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/OrderMapper.java b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/OrderMapper.java new file mode 100644 index 0000000000..8b33ab17d9 --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/main/java/org/mapstruct/itest/usestypegeneration/usage/OrderMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.usestypegeneration.usage; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = StringUtils.class) +public interface OrderMapper { + + OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class ); + + OrderDto orderToDto(Order order); +} diff --git a/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/usestypegeneration/usage/GeneratedUsesTypeTest.java b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/usestypegeneration/usage/GeneratedUsesTypeTest.java new file mode 100644 index 0000000000..55ea60a0ad --- /dev/null +++ b/integrationtest/src/test/resources/usesTypeGenerationTest/usage/src/test/java/org/mapstruct/itest/usestypegeneration/usage/GeneratedUsesTypeTest.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.itest.usestypegeneration.usage; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Integration test for using MapStruct with another annotation processor that generates the other mappers for uses + * + * @author Filip Hrisafov + */ +class GeneratedUsesTypeTest { + + @Test + void considersPropertiesOnGeneratedSourceAndTargetTypes() { + Order order = new Order(); + order.setItem( "my item" ); + + OrderDto dto = OrderMapper.INSTANCE.orderToDto( order ); + assertThat( dto.getItem() ).isEqualTo( "MY ITEM" ); + } +} diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000000..a21f2c22c4 --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,2 @@ +jdk: + - openjdk21 diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000..bd8896bf22 --- /dev/null +++ b/mvnw @@ -0,0 +1,295 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Apache Maven Wrapper startup batch script, version 3.3.4 +# +# Optional ENV vars +# ----------------- +# JAVA_HOME - location of a JDK home dir, required when download maven via java source +# MVNW_REPOURL - repo url base for downloading maven distribution +# MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +# MVNW_VERBOSE - true: enable verbose log; debug: trace the mvnw script; others: silence the output +# ---------------------------------------------------------------------------- + +set -euf +[ "${MVNW_VERBOSE-}" != debug ] || set -x + +# OS specific support. +native_path() { printf %s\\n "$1"; } +case "$(uname)" in +CYGWIN* | MINGW*) + [ -z "${JAVA_HOME-}" ] || JAVA_HOME="$(cygpath --unix "$JAVA_HOME")" + native_path() { cygpath --path --windows "$1"; } + ;; +esac + +# set JAVACMD and JAVACCMD +set_java_home() { + # For Cygwin and MinGW, ensure paths are in Unix format before anything is touched + if [ -n "${JAVA_HOME-}" ]; then + if [ -x "$JAVA_HOME/jre/sh/java" ]; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACCMD="$JAVA_HOME/jre/sh/javac" + else + JAVACMD="$JAVA_HOME/bin/java" + JAVACCMD="$JAVA_HOME/bin/javac" + + if [ ! -x "$JAVACMD" ] || [ ! -x "$JAVACCMD" ]; then + echo "The JAVA_HOME environment variable is not defined correctly, so mvnw cannot run." >&2 + echo "JAVA_HOME is set to \"$JAVA_HOME\", but \"\$JAVA_HOME/bin/java\" or \"\$JAVA_HOME/bin/javac\" does not exist." >&2 + return 1 + fi + fi + else + JAVACMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v java + )" || : + JAVACCMD="$( + 'set' +e + 'unset' -f command 2>/dev/null + 'command' -v javac + )" || : + + if [ ! -x "${JAVACMD-}" ] || [ ! -x "${JAVACCMD-}" ]; then + echo "The java/javac command does not exist in PATH nor is JAVA_HOME set, so mvnw cannot run." >&2 + return 1 + fi + fi +} + +# hash string like Java String::hashCode +hash_string() { + str="${1:-}" h=0 + while [ -n "$str" ]; do + char="${str%"${str#?}"}" + h=$(((h * 31 + $(LC_CTYPE=C printf %d "'$char")) % 4294967296)) + str="${str#?}" + done + printf %x\\n $h +} + +verbose() { :; } +[ "${MVNW_VERBOSE-}" != true ] || verbose() { printf %s\\n "${1-}"; } + +die() { + printf %s\\n "$1" >&2 + exit 1 +} + +trim() { + # MWRAPPER-139: + # Trims trailing and leading whitespace, carriage returns, tabs, and linefeeds. + # Needed for removing poorly interpreted newline sequences when running in more + # exotic environments such as mingw bash on Windows. + printf "%s" "${1}" | tr -d '[:space:]' +} + +scriptDir="$(dirname "$0")" +scriptName="$(basename "$0")" + +# parse distributionUrl and optional distributionSha256Sum, requires .mvn/wrapper/maven-wrapper.properties +while IFS="=" read -r key value; do + case "${key-}" in + distributionUrl) distributionUrl=$(trim "${value-}") ;; + distributionSha256Sum) distributionSha256Sum=$(trim "${value-}") ;; + esac +done <"$scriptDir/.mvn/wrapper/maven-wrapper.properties" +[ -n "${distributionUrl-}" ] || die "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" + +case "${distributionUrl##*/}" in +maven-mvnd-*bin.*) + MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ + case "${PROCESSOR_ARCHITECTURE-}${PROCESSOR_ARCHITEW6432-}:$(uname -a)" in + *AMD64:CYGWIN* | *AMD64:MINGW*) distributionPlatform=windows-amd64 ;; + :Darwin*x86_64) distributionPlatform=darwin-amd64 ;; + :Darwin*arm64) distributionPlatform=darwin-aarch64 ;; + :Linux*x86_64*) distributionPlatform=linux-amd64 ;; + *) + echo "Cannot detect native platform for mvnd on $(uname)-$(uname -m), use pure java version" >&2 + distributionPlatform=linux-amd64 + ;; + esac + distributionUrl="${distributionUrl%-bin.*}-$distributionPlatform.zip" + ;; +maven-mvnd-*) MVN_CMD=mvnd.sh _MVNW_REPO_PATTERN=/maven/mvnd/ ;; +*) MVN_CMD="mvn${scriptName#mvnw}" _MVNW_REPO_PATTERN=/org/apache/maven/ ;; +esac + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +[ -z "${MVNW_REPOURL-}" ] || distributionUrl="$MVNW_REPOURL$_MVNW_REPO_PATTERN${distributionUrl#*"$_MVNW_REPO_PATTERN"}" +distributionUrlName="${distributionUrl##*/}" +distributionUrlNameMain="${distributionUrlName%.*}" +distributionUrlNameMain="${distributionUrlNameMain%-bin}" +MAVEN_USER_HOME="${MAVEN_USER_HOME:-${HOME}/.m2}" +MAVEN_HOME="${MAVEN_USER_HOME}/wrapper/dists/${distributionUrlNameMain-}/$(hash_string "$distributionUrl")" + +exec_maven() { + unset MVNW_VERBOSE MVNW_USERNAME MVNW_PASSWORD MVNW_REPOURL || : + exec "$MAVEN_HOME/bin/$MVN_CMD" "$@" || die "cannot exec $MAVEN_HOME/bin/$MVN_CMD" +} + +if [ -d "$MAVEN_HOME" ]; then + verbose "found existing MAVEN_HOME at $MAVEN_HOME" + exec_maven "$@" +fi + +case "${distributionUrl-}" in +*?-bin.zip | *?maven-mvnd-?*-?*.zip) ;; +*) die "distributionUrl is not valid, must match *-bin.zip or maven-mvnd-*.zip, but found '${distributionUrl-}'" ;; +esac + +# prepare tmp dir +if TMP_DOWNLOAD_DIR="$(mktemp -d)" && [ -d "$TMP_DOWNLOAD_DIR" ]; then + clean() { rm -rf -- "$TMP_DOWNLOAD_DIR"; } + trap clean HUP INT TERM EXIT +else + die "cannot create temp dir" +fi + +mkdir -p -- "${MAVEN_HOME%/*}" + +# Download and Install Apache Maven +verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +verbose "Downloading from: $distributionUrl" +verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +# select .zip or .tar.gz +if ! command -v unzip >/dev/null; then + distributionUrl="${distributionUrl%.zip}.tar.gz" + distributionUrlName="${distributionUrl##*/}" +fi + +# verbose opt +__MVNW_QUIET_WGET=--quiet __MVNW_QUIET_CURL=--silent __MVNW_QUIET_UNZIP=-q __MVNW_QUIET_TAR='' +[ "${MVNW_VERBOSE-}" != true ] || __MVNW_QUIET_WGET='' __MVNW_QUIET_CURL='' __MVNW_QUIET_UNZIP='' __MVNW_QUIET_TAR=v + +# normalize http auth +case "${MVNW_PASSWORD:+has-password}" in +'') MVNW_USERNAME='' MVNW_PASSWORD='' ;; +has-password) [ -n "${MVNW_USERNAME-}" ] || MVNW_USERNAME='' MVNW_PASSWORD='' ;; +esac + +if [ -z "${MVNW_USERNAME-}" ] && command -v wget >/dev/null; then + verbose "Found wget ... using wget" + wget ${__MVNW_QUIET_WGET:+"$__MVNW_QUIET_WGET"} "$distributionUrl" -O "$TMP_DOWNLOAD_DIR/$distributionUrlName" || die "wget: Failed to fetch $distributionUrl" +elif [ -z "${MVNW_USERNAME-}" ] && command -v curl >/dev/null; then + verbose "Found curl ... using curl" + curl ${__MVNW_QUIET_CURL:+"$__MVNW_QUIET_CURL"} -f -L -o "$TMP_DOWNLOAD_DIR/$distributionUrlName" "$distributionUrl" || die "curl: Failed to fetch $distributionUrl" +elif set_java_home; then + verbose "Falling back to use Java to download" + javaSource="$TMP_DOWNLOAD_DIR/Downloader.java" + targetZip="$TMP_DOWNLOAD_DIR/$distributionUrlName" + cat >"$javaSource" <<-END + public class Downloader extends java.net.Authenticator + { + protected java.net.PasswordAuthentication getPasswordAuthentication() + { + return new java.net.PasswordAuthentication( System.getenv( "MVNW_USERNAME" ), System.getenv( "MVNW_PASSWORD" ).toCharArray() ); + } + public static void main( String[] args ) throws Exception + { + setDefault( new Downloader() ); + java.nio.file.Files.copy( java.net.URI.create( args[0] ).toURL().openStream(), java.nio.file.Paths.get( args[1] ).toAbsolutePath().normalize() ); + } + } + END + # For Cygwin/MinGW, switch paths to Windows format before running javac and java + verbose " - Compiling Downloader.java ..." + "$(native_path "$JAVACCMD")" "$(native_path "$javaSource")" || die "Failed to compile Downloader.java" + verbose " - Running Downloader.java ..." + "$(native_path "$JAVACMD")" -cp "$(native_path "$TMP_DOWNLOAD_DIR")" Downloader "$distributionUrl" "$(native_path "$targetZip")" +fi + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +if [ -n "${distributionSha256Sum-}" ]; then + distributionSha256Result=false + if [ "$MVN_CMD" = mvnd.sh ]; then + echo "Checksum validation is not supported for maven-mvnd." >&2 + echo "Please disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + elif command -v sha256sum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | sha256sum -c - >/dev/null 2>&1; then + distributionSha256Result=true + fi + elif command -v shasum >/dev/null; then + if echo "$distributionSha256Sum $TMP_DOWNLOAD_DIR/$distributionUrlName" | shasum -a 256 -c >/dev/null 2>&1; then + distributionSha256Result=true + fi + else + echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." >&2 + echo "Please install either command, or disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." >&2 + exit 1 + fi + if [ $distributionSha256Result = false ]; then + echo "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised." >&2 + echo "If you updated your Maven version, you need to update the specified distributionSha256Sum property." >&2 + exit 1 + fi +fi + +# unzip and move +if command -v unzip >/dev/null; then + unzip ${__MVNW_QUIET_UNZIP:+"$__MVNW_QUIET_UNZIP"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -d "$TMP_DOWNLOAD_DIR" || die "failed to unzip" +else + tar xzf${__MVNW_QUIET_TAR:+"$__MVNW_QUIET_TAR"} "$TMP_DOWNLOAD_DIR/$distributionUrlName" -C "$TMP_DOWNLOAD_DIR" || die "failed to untar" +fi + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +actualDistributionDir="" + +# First try the expected directory name (for regular distributions) +if [ -d "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain" ]; then + if [ -f "$TMP_DOWNLOAD_DIR/$distributionUrlNameMain/bin/$MVN_CMD" ]; then + actualDistributionDir="$distributionUrlNameMain" + fi +fi + +# If not found, search for any directory with the Maven executable (for snapshots) +if [ -z "$actualDistributionDir" ]; then + # enable globbing to iterate over items + set +f + for dir in "$TMP_DOWNLOAD_DIR"/*; do + if [ -d "$dir" ]; then + if [ -f "$dir/bin/$MVN_CMD" ]; then + actualDistributionDir="$(basename "$dir")" + break + fi + fi + done + set -f +fi + +if [ -z "$actualDistributionDir" ]; then + verbose "Contents of $TMP_DOWNLOAD_DIR:" + verbose "$(ls -la "$TMP_DOWNLOAD_DIR")" + die "Could not find Maven distribution directory in extracted archive" +fi + +verbose "Found extracted Maven distribution directory: $actualDistributionDir" +printf %s\\n "$distributionUrl" >"$TMP_DOWNLOAD_DIR/$actualDistributionDir/mvnw.url" +mv -- "$TMP_DOWNLOAD_DIR/$actualDistributionDir" "$MAVEN_HOME" || [ -d "$MAVEN_HOME" ] || die "fail to move MAVEN_HOME" + +clean || : +exec_maven "$@" diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000000..92450f9327 --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,189 @@ +<# : batch portion +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Apache Maven Wrapper startup batch script, version 3.3.4 +@REM +@REM Optional ENV vars +@REM MVNW_REPOURL - repo url base for downloading maven distribution +@REM MVNW_USERNAME/MVNW_PASSWORD - user and password for downloading maven +@REM MVNW_VERBOSE - true: enable verbose log; others: silence the output +@REM ---------------------------------------------------------------------------- + +@IF "%__MVNW_ARG0_NAME__%"=="" (SET __MVNW_ARG0_NAME__=%~nx0) +@SET __MVNW_CMD__= +@SET __MVNW_ERROR__= +@SET __MVNW_PSMODULEP_SAVE=%PSModulePath% +@SET PSModulePath= +@FOR /F "usebackq tokens=1* delims==" %%A IN (`powershell -noprofile "& {$scriptDir='%~dp0'; $script='%__MVNW_ARG0_NAME__%'; icm -ScriptBlock ([Scriptblock]::Create((Get-Content -Raw '%~f0'))) -NoNewScope}"`) DO @( + IF "%%A"=="MVN_CMD" (set __MVNW_CMD__=%%B) ELSE IF "%%B"=="" (echo %%A) ELSE (echo %%A=%%B) +) +@SET PSModulePath=%__MVNW_PSMODULEP_SAVE% +@SET __MVNW_PSMODULEP_SAVE= +@SET __MVNW_ARG0_NAME__= +@SET MVNW_USERNAME= +@SET MVNW_PASSWORD= +@IF NOT "%__MVNW_CMD__%"=="" ("%__MVNW_CMD__%" %*) +@echo Cannot start maven from wrapper >&2 && exit /b 1 +@GOTO :EOF +: end batch / begin powershell #> + +$ErrorActionPreference = "Stop" +if ($env:MVNW_VERBOSE -eq "true") { + $VerbosePreference = "Continue" +} + +# calculate distributionUrl, requires .mvn/wrapper/maven-wrapper.properties +$distributionUrl = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionUrl +if (!$distributionUrl) { + Write-Error "cannot read distributionUrl property in $scriptDir/.mvn/wrapper/maven-wrapper.properties" +} + +switch -wildcard -casesensitive ( $($distributionUrl -replace '^.*/','') ) { + "maven-mvnd-*" { + $USE_MVND = $true + $distributionUrl = $distributionUrl -replace '-bin\.[^.]*$',"-windows-amd64.zip" + $MVN_CMD = "mvnd.cmd" + break + } + default { + $USE_MVND = $false + $MVN_CMD = $script -replace '^mvnw','mvn' + break + } +} + +# apply MVNW_REPOURL and calculate MAVEN_HOME +# maven home pattern: ~/.m2/wrapper/dists/{apache-maven-,maven-mvnd--}/ +if ($env:MVNW_REPOURL) { + $MVNW_REPO_PATTERN = if ($USE_MVND -eq $False) { "/org/apache/maven/" } else { "/maven/mvnd/" } + $distributionUrl = "$env:MVNW_REPOURL$MVNW_REPO_PATTERN$($distributionUrl -replace "^.*$MVNW_REPO_PATTERN",'')" +} +$distributionUrlName = $distributionUrl -replace '^.*/','' +$distributionUrlNameMain = $distributionUrlName -replace '\.[^.]*$','' -replace '-bin$','' + +$MAVEN_M2_PATH = "$HOME/.m2" +if ($env:MAVEN_USER_HOME) { + $MAVEN_M2_PATH = "$env:MAVEN_USER_HOME" +} + +if (-not (Test-Path -Path $MAVEN_M2_PATH)) { + New-Item -Path $MAVEN_M2_PATH -ItemType Directory | Out-Null +} + +$MAVEN_WRAPPER_DISTS = $null +if ((Get-Item $MAVEN_M2_PATH).Target[0] -eq $null) { + $MAVEN_WRAPPER_DISTS = "$MAVEN_M2_PATH/wrapper/dists" +} else { + $MAVEN_WRAPPER_DISTS = (Get-Item $MAVEN_M2_PATH).Target[0] + "/wrapper/dists" +} + +$MAVEN_HOME_PARENT = "$MAVEN_WRAPPER_DISTS/$distributionUrlNameMain" +$MAVEN_HOME_NAME = ([System.Security.Cryptography.SHA256]::Create().ComputeHash([byte[]][char[]]$distributionUrl) | ForEach-Object {$_.ToString("x2")}) -join '' +$MAVEN_HOME = "$MAVEN_HOME_PARENT/$MAVEN_HOME_NAME" + +if (Test-Path -Path "$MAVEN_HOME" -PathType Container) { + Write-Verbose "found existing MAVEN_HOME at $MAVEN_HOME" + Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" + exit $? +} + +if (! $distributionUrlNameMain -or ($distributionUrlName -eq $distributionUrlNameMain)) { + Write-Error "distributionUrl is not valid, must end with *-bin.zip, but found $distributionUrl" +} + +# prepare tmp dir +$TMP_DOWNLOAD_DIR_HOLDER = New-TemporaryFile +$TMP_DOWNLOAD_DIR = New-Item -Itemtype Directory -Path "$TMP_DOWNLOAD_DIR_HOLDER.dir" +$TMP_DOWNLOAD_DIR_HOLDER.Delete() | Out-Null +trap { + if ($TMP_DOWNLOAD_DIR.Exists) { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } + } +} + +New-Item -Itemtype Directory -Path "$MAVEN_HOME_PARENT" -Force | Out-Null + +# Download and Install Apache Maven +Write-Verbose "Couldn't find MAVEN_HOME, downloading and installing it ..." +Write-Verbose "Downloading from: $distributionUrl" +Write-Verbose "Downloading to: $TMP_DOWNLOAD_DIR/$distributionUrlName" + +$webclient = New-Object System.Net.WebClient +if ($env:MVNW_USERNAME -and $env:MVNW_PASSWORD) { + $webclient.Credentials = New-Object System.Net.NetworkCredential($env:MVNW_USERNAME, $env:MVNW_PASSWORD) +} +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 +$webclient.DownloadFile($distributionUrl, "$TMP_DOWNLOAD_DIR/$distributionUrlName") | Out-Null + +# If specified, validate the SHA-256 sum of the Maven distribution zip file +$distributionSha256Sum = (Get-Content -Raw "$scriptDir/.mvn/wrapper/maven-wrapper.properties" | ConvertFrom-StringData).distributionSha256Sum +if ($distributionSha256Sum) { + if ($USE_MVND) { + Write-Error "Checksum validation is not supported for maven-mvnd. `nPlease disable validation by removing 'distributionSha256Sum' from your maven-wrapper.properties." + } + Import-Module $PSHOME\Modules\Microsoft.PowerShell.Utility -Function Get-FileHash + if ((Get-FileHash "$TMP_DOWNLOAD_DIR/$distributionUrlName" -Algorithm SHA256).Hash.ToLower() -ne $distributionSha256Sum) { + Write-Error "Error: Failed to validate Maven distribution SHA-256, your Maven distribution might be compromised. If you updated your Maven version, you need to update the specified distributionSha256Sum property." + } +} + +# unzip and move +Expand-Archive "$TMP_DOWNLOAD_DIR/$distributionUrlName" -DestinationPath "$TMP_DOWNLOAD_DIR" | Out-Null + +# Find the actual extracted directory name (handles snapshots where filename != directory name) +$actualDistributionDir = "" + +# First try the expected directory name (for regular distributions) +$expectedPath = Join-Path "$TMP_DOWNLOAD_DIR" "$distributionUrlNameMain" +$expectedMvnPath = Join-Path "$expectedPath" "bin/$MVN_CMD" +if ((Test-Path -Path $expectedPath -PathType Container) -and (Test-Path -Path $expectedMvnPath -PathType Leaf)) { + $actualDistributionDir = $distributionUrlNameMain +} + +# If not found, search for any directory with the Maven executable (for snapshots) +if (!$actualDistributionDir) { + Get-ChildItem -Path "$TMP_DOWNLOAD_DIR" -Directory | ForEach-Object { + $testPath = Join-Path $_.FullName "bin/$MVN_CMD" + if (Test-Path -Path $testPath -PathType Leaf) { + $actualDistributionDir = $_.Name + } + } +} + +if (!$actualDistributionDir) { + Write-Error "Could not find Maven distribution directory in extracted archive" +} + +Write-Verbose "Found extracted Maven distribution directory: $actualDistributionDir" +Rename-Item -Path "$TMP_DOWNLOAD_DIR/$actualDistributionDir" -NewName $MAVEN_HOME_NAME | Out-Null +try { + Move-Item -Path "$TMP_DOWNLOAD_DIR/$MAVEN_HOME_NAME" -Destination $MAVEN_HOME_PARENT | Out-Null +} catch { + if (! (Test-Path -Path "$MAVEN_HOME" -PathType Container)) { + Write-Error "fail to move MAVEN_HOME" + } +} finally { + try { Remove-Item $TMP_DOWNLOAD_DIR -Recurse -Force | Out-Null } + catch { Write-Warning "Cannot remove $TMP_DOWNLOAD_DIR" } +} + +Write-Output "MVN_CMD=$MAVEN_HOME/bin/$MVN_CMD" diff --git a/parent/pom.xml b/parent/pom.xml index a088ddd778..b444c1847a 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -1,22 +1,9 @@ @@ -24,26 +11,48 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT pom MapStruct Parent An annotation processor for generating type-safe bean mappers - http://mapstruct.org/ + https://mapstruct.org/ 2012 UTF-8 - 1.0.0 - 1.2 - 2.19.1 - 3.0.0-M1 - 4.0.3.RELEASE - 0.26.0 - 7.2 - + + mapstruct/mapstruct + /tmp/repository + 1.8 + ${java.version} + ${java.version} + + ${git.commit.author.time} + + 1.0.0.Alpha3 + 3.6.2 + 3.5.4 + 3.12.0 + 7.0.3 + 1.6.0 + 13.0.0 + 5.14.1 + 2.2.0 + 1.24.0 1 - 3.7.0 + 3.27.7 + + + jdt_apt + + 1.8 + 3.25.5 + 2.3.2 + 2.3.0 @@ -59,7 +68,12 @@ gunnarmorling Gunnar Morling gunnar@mapstruct.org - http://www.gunnarmorling.de/ + https://www.morling.dev/ + + + filiphr + Filip Hrisafov + https://github.com/filiphr/ @@ -74,12 +88,12 @@ sonatype-nexus-staging Nexus Release Repository - https://oss.sonatype.org/service/local/staging/deploy/maven2/ + https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/ sonatype-nexus-snapshots Sonatype Nexus Snapshots - https://oss.sonatype.org/content/repositories/snapshots/ + https://central.sonatype.com/repository/maven-snapshots/ @@ -89,8 +103,8 @@ - Travis CI - https://travis-ci.org/mapstruct/mapstruct + Github Actions + https://github.com/mapstruct/mapstruct/actions @@ -100,16 +114,12 @@ - - 3.0.3 - - org.freemarker freemarker - 2.3.21 + 2.3.34 org.assertj @@ -119,17 +129,17 @@ com.google.guava guava - 19.0 + 32.0.0-jre - com.jolira - hickory - ${com.jolira.hickory.version} + org.mapstruct.tools.gem + gem-api + ${org.mapstruct.gem.version} - junit - junit - 4.12 + org.mapstruct.tools.gem + gem-processor + ${org.mapstruct.gem.version} com.puppycrawl.tools @@ -137,33 +147,69 @@ ${com.puppycrawl.tools.checkstyle.version} + + org.jetbrains.kotlin + kotlin-bom + ${kotlin.version} + pom + import + + + org.jetbrains.kotlin + kotlin-metadata-jvm + ${kotlin.version} + + + org.junit + junit-bom + ${org.junit.jupiter.version} + pom + import + + + org.junit-pioneer + junit-pioneer + ${junit-pioneer.version} + + javax.enterprise cdi-api - 1.2 + 2.0.SP1 + + + jakarta.enterprise + jakarta.enterprise.cdi-api + 4.0.1 javax.inject javax.inject 1 + + jakarta.inject + jakarta.inject-api + 2.0.1 + org.jboss.arquillian arquillian-bom - 1.0.2.Final + 1.7.2.Final import pom org.jboss.arquillian.container arquillian-weld-se-embedded-1.1 - 1.0.0.CR7 + 1.0.0.Final org.jboss.weld - weld-core - 2.3.2.Final + weld-core-impl + 3.1.8.Final + test org.glassfish @@ -197,7 +243,7 @@ org.projectlombok lombok - 1.16.18 + 1.18.38 org.immutables @@ -209,17 +255,53 @@ auto-value 1.5 + + com.google.protobuf + protobuf-java + ${protobuf.version} + org.inferred freebuilder 1.14.6 + + + org.jspecify + jspecify + 1.0.0 + + joda-time joda-time - 2.9 + 2.12.5 + + + + + + javax.xml.bind + jaxb-api + 2.3.1 + + + org.glassfish.jaxb + jaxb-runtime + ${jaxb-runtime.version} + + + + jakarta.xml.bind + jakarta.xml.bind-api + 3.0.1 + + + com.sun.xml.bind + jaxb-impl + 3.0.2 @@ -231,28 +313,33 @@ org.codehaus.plexus plexus-container-default - 1.6 + 1.7.1 org.codehaus.plexus - plexus-utils - 3.0.20 + plexus-component-annotations + 1.7.1 - - - ${project.groupId} - mapstruct-common - ${project.version} + org.codehaus.plexus + plexus-classworlds + 2.5.1 - ${project.groupId} - mapstruct - ${project.version} + org.codehaus.plexus + plexus-utils + 3.0.24 + + + commons-io + commons-io + 2.15.0 + + ${project.groupId} - mapstruct-jdk8 + mapstruct ${project.version} @@ -286,12 +373,12 @@ org.apache.maven.plugins maven-assembly-plugin - 2.4 + 3.8.0 org.apache.maven.plugins maven-checkstyle-plugin - 2.17 + 3.6.0 build-config/checkstyle.xml true @@ -305,7 +392,7 @@ specified as patterns within a source folder, so we can't exclude generated-sources altogether --> - **/*Prism.java,*/itest/jaxb/xsd/* + **/*Gem.java,*/itest/jaxb/xsd/* @@ -323,36 +410,26 @@ org.apache.maven.plugins maven-clean-plugin - 2.5 + 3.5.0 org.apache.maven.plugins maven-compiler-plugin - 3.3 - - 1.6 - 1.6 - -proc:none - + 3.15.0 org.apache.maven.plugins maven-dependency-plugin - 2.8 + 3.9.0 org.apache.maven.plugins maven-deploy-plugin - 2.8.2 + 3.1.4 true - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - org.apache.maven.plugins maven-enforcer-plugin @@ -361,14 +438,14 @@ de.andrena.tools.nopackagecycles no-package-cycles-enforcer-rule - 1.0.5 + 1.0.9 org.apache.felix maven-bundle-plugin - 3.0.1 + 5.1.1 bundle-manifest @@ -382,12 +459,12 @@ org.apache.maven.plugins maven-install-plugin - 2.5.2 + 3.1.4 org.apache.maven.plugins maven-jar-plugin - 3.0.2 + 3.5.0 org.apache.maven.plugins @@ -395,38 +472,24 @@ ${org.apache.maven.plugins.javadoc.version} true - org.mapstruct.ap.internal.prism;org.mapstruct.itest.jaxb.xsd.* - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - -DskipTests ${add.release.arguments} - clean install - false - true - @{project.version} - true - false - release + org.mapstruct.ap.internal.gem;org.mapstruct.itest.jaxb.xsd.* + 8 org.apache.maven.plugins maven-resources-plugin - 2.6 + 3.4.0 org.apache.maven.plugins maven-source-plugin - 3.0.1 + 3.4.0 org.apache.maven.plugins maven-site-plugin - 3.6 + 3.21.0 org.apache.maven.plugins @@ -434,49 +497,41 @@ ${org.apache.maven.plugins.surefire.version} ${forkCount} - -Xms1024m -Xmx3072m - - - org.apache.maven.surefire - surefire-junit47 - ${org.apache.maven.plugins.surefire.version} - - org.apache.maven.plugins maven-shade-plugin - 2.3 + 3.6.1 - com.mycila.maven-license-plugin - maven-license-plugin - 1.10.b1 + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} - org.bsc.maven - maven-processor-plugin - 2.2.4 - - - org.codehaus.mojo - build-helper-maven-plugin - 1.8 + com.mycila + license-maven-plugin + 4.6 org.codehaus.mojo animal-sniffer-maven-plugin - 1.9 + 1.20 org.ow2.asm - asm-all - 5.0.2 + asm + 7.0 + + org.codehaus.mojo + versions-maven-plugin + 2.16.2 + org.eclipse.m2e lifecycle-mapping @@ -531,12 +586,12 @@ org.jacoco jacoco-maven-plugin - 0.7.9 + 0.8.14 org.jvnet.jaxb2.maven2 maven-jaxb2-plugin - 0.9.0 + 0.14.0 org.codehaus.mojo @@ -546,7 +601,7 @@ de.thetaphi forbiddenapis - 2.3 + 2.6 ${project.basedir}/../etc/forbidden-apis.txt @@ -556,7 +611,7 @@ com.github.siom79.japicmp japicmp-maven-plugin - 0.10.0 + 0.25.4 verify @@ -574,44 +629,69 @@ \d+\.\d+\.\d+\.Final true + + + METHOD_NEW_DEFAULT + true + false + MINOR + + + + org.codehaus.mojo + flatten-maven-plugin + 1.2.2 + - com.mycila.maven-license-plugin - maven-license-plugin + com.mycila + license-maven-plugin -

    ${basedir}/../etc/license.txt
    true - - .idea/** - **/build-config/checkstyle.xml - **/build-config/import-control.xml - copyright.txt - **/LICENSE.txt - **/mapstruct.xml - **/toolchains-*.xml - **/travis-settings.xml - **/eclipse-formatter-config.xml - **/forbidden-apis.txt - **/checkstyle-for-generated-sources.xml - **/nb-configuration.xml - maven-settings.xml - readme.md - CONTRIBUTING.md - .gitattributes - .gitignore - .factorypath - .checkstyle - *.yml - **/*.asciidoc - **/binding.xjb - + + +
    ${basedir}/../etc/license.txt
    + + **/.idea/** + **/.mvn/** + **/build-config/checkstyle.xml + **/build-config/import-control.xml + copyright.txt + **/LICENSE.txt + **/mapstruct.xml + **/ci-settings.xml + **/eclipse-formatter-config.xml + **/forbidden-apis.txt + **/checkstyle-for-generated-sources.xml + **/nb-configuration.xml + **/junit-platform.properties + maven-settings.xml + readme.md + CONTRIBUTING.md + NEXT_RELEASE_CHANGELOG.md + .gitattributes + .gitignore + .factorypath + .checkstyle + *.yml + mvnw* + **/*.asciidoc + **/binding.xjb + **/*.flattened-pom.xml + +
    +
    + + SLASHSTAR_STYLE + SLASHSTAR_STYLE + @@ -634,9 +714,12 @@ org.codehaus.mojo.signature - java16 + java18 1.0 + + org.mapstruct.ap.internal.util.IgnoreJRERequirement + @@ -656,7 +739,7 @@ - [1.8,) + [${minimum.java.version},) @@ -674,7 +757,9 @@ test-compile - + + false + @@ -693,12 +778,49 @@ + + org.codehaus.mojo + flatten-maven-plugin + + + + flatten + package + + flatten + + + true + ossrh + + expand + + + + + flatten-clean + clean + + clean + + + + + + org.codehaus.mojo + versions-maven-plugin + - release + publication + + + release + + @@ -725,18 +847,94 @@ + + + + + stage + + local::file:${maven.multiModuleProjectDirectory}/target/staging-deploy + + + deploy + + + + jreleaser + + - org.apache.maven.plugins - maven-gpg-plugin - - - sign-artifacts - verify - - sign - - - + org.jreleaser + jreleaser-maven-plugin + ${jreleaser.plugin.version} + + true + + + Mapstruct + + https://mapstruct.org/ + https://mapstruct.org/documentation/stable/reference/html/ + + + + ALWAYS + + ALWAYS + true + + + + false + + + + + + RELEASE + https://central.sonatype.com/api/v1/publisher + ${maven.multiModuleProjectDirectory}/target/staging-deploy + + + org.mapstruct + mapstruct-jdk8 + false + false + + + + + + + + + {{projectVersion}} + {{projectVersion}} + + ${maven.multiModuleProjectDirectory}/NEXT_RELEASE_CHANGELOG.md + + + \d+\.\d+\.\d+\.(Alpha|Beta|M|RC)\d* + + + legacy + + + + + + ${maven.multiModuleProjectDirectory}/distribution/target/mapstruct-{{projectVersion}}-dist.tar.gz + + + ${maven.multiModuleProjectDirectory}/distribution/target/mapstruct-{{projectVersion}}-dist.zip + + + + + diff --git a/pom.xml b/pom.xml index d920177b63..c753e3c1e4 100644 --- a/pom.xml +++ b/pom.xml @@ -1,22 +1,9 @@ @@ -26,7 +13,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT parent/pom.xml @@ -37,11 +24,9 @@ parent build-config - core-common core core-jdk8 processor - integrationtest true @@ -50,12 +35,17 @@ - com.mycila.maven-license-plugin - maven-license-plugin + com.mycila + license-maven-plugin -
    etc/license.txt
    + + +
    etc/license.txt
    +
    +
    XML_STYLE + SLASHSTAR_STYLE
    @@ -84,5 +74,17 @@ distribution
    + + test + + + release + !true + + + + integrationtest + +
    diff --git a/processor/pom.xml b/processor/pom.xml index da0b426d0c..e317365aec 100644 --- a/processor/pom.xml +++ b/processor/pom.xml @@ -1,22 +1,9 @@ @@ -25,7 +12,7 @@ org.mapstruct mapstruct-parent - 1.3.0-SNAPSHOT + 1.7.0-SNAPSHOT ../parent/pom.xml @@ -34,10 +21,10 @@ MapStruct Processor - ${project.build.directory}/generated-sources/prims + 21 @@ -46,30 +33,39 @@ org.freemarker freemarker - - - com.jolira - hickory - provided + org.mapstruct.tools.gem + gem-api ${project.groupId} mapstruct provided + + org.jetbrains.kotlin + kotlin-metadata-jvm + provided + + + org.jetbrains.kotlin + kotlin-compiler-embeddable + test + org.eclipse.tycho tycho-compiler-jdt - provided - true + test - junit - junit + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine test @@ -98,6 +94,16 @@ javax.inject test + + jakarta.inject + jakarta.inject-api + test + + + jakarta.enterprise + jakarta.enterprise.cdi-api + test + @@ -123,12 +129,38 @@ test + + org.junit.platform + junit-platform-launcher + test + + + + org.junit-pioneer + junit-pioneer + test + + joda-time joda-time test + + + + org.jspecify + jspecify + test + + + + jakarta.xml.bind + jakarta.xml.bind-api + provided + true + @@ -142,10 +174,18 @@ org.mapstruct.processor + annotation-processor
    + + org.apache.maven.plugins + maven-javadoc-plugin + + all,-missing + + org.apache.maven.plugins maven-surefire-plugin @@ -192,6 +232,12 @@ true + + + org.freemarker:* + org.mapstruct.tools.gem:gem-api + + org.freemarker:freemarker @@ -199,17 +245,44 @@ META-INF/*.* + + org.mapstruct.tools.gem:gem-api + + META-INF/*.* + **/GemDefinition.class + **/GemDefinitions.class + + freemarker org.mapstruct.ap.shaded.freemarker + + org.mapstruct.tools.gem + org.mapstruct.ap.shaded.org.mapstruct.tools.gem + + + + org.codehaus.mojo + flatten-maven-plugin + + + + flatten + package + + flatten + + + + org.apache.maven.plugins maven-dependency-plugin @@ -234,52 +307,82 @@ - org.bsc.maven - maven-processor-plugin + org.jetbrains.kotlin + + kotlin-maven-plugin - ${prism.directory} - - net.java.dev.hickory.prism.internal.PrismGenerator - - + false - process - generate-sources + kotlin-compile + compile + + compile + + + ${minimum.java.version} + + src/main/kotlin + + src/main/java + + + + + kotlin-test-compile + test-compile - process + test-compile + + ${minimum.java.version} + + src/test/java + + - - - com.jolira - hickory - ${com.jolira.hickory.version} - - - org.eclipse.tycho - tycho-compiler-jdt - ${org.eclipse.tycho.compiler-jdt.version} - - - org.codehaus.mojo - build-helper-maven-plugin + org.apache.maven.plugins + maven-compiler-plugin + + ${minimum.java.version} + + + org.mapstruct.tools.gem + gem-processor + ${org.mapstruct.gem.version} + + + + + - add-source - generate-sources + default-compile + none + + + default-testCompile + none + + + + + java-compile + compile - add-source + compile + + + + java-test-compile + test-compile + + testCompile - - - ${prism.directory} - - @@ -359,4 +462,20 @@ + + + jdk-11-or-newer + + [11 + + + + javax.xml.bind + jaxb-api + provided + true + + + + diff --git a/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java b/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java index ec0db40415..50831a8f42 100644 --- a/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/MappingProcessor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap; @@ -26,34 +13,42 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.ServiceLoader; import java.util.Set; - +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.Processor; import javax.annotation.processing.RoundEnvironment; import javax.annotation.processing.SupportedAnnotationTypes; -import javax.annotation.processing.SupportedOptions; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; +import javax.lang.model.element.Name; +import javax.lang.model.element.QualifiedNameable; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.ElementKindVisitor6; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementKindVisitor8; import javax.tools.Diagnostic.Kind; +import org.mapstruct.ap.internal.gem.MapperGem; import org.mapstruct.ap.internal.model.Mapper; +import org.mapstruct.ap.internal.option.MappingOption; import org.mapstruct.ap.internal.option.Options; -import org.mapstruct.ap.internal.prism.MapperPrism; -import org.mapstruct.ap.internal.prism.ReportingPolicyPrism; import org.mapstruct.ap.internal.processor.DefaultModelElementProcessorContext; import org.mapstruct.ap.internal.processor.ModelElementProcessor; import org.mapstruct.ap.internal.processor.ModelElementProcessor.ProcessorContext; import org.mapstruct.ap.internal.util.AnnotationProcessingException; import org.mapstruct.ap.internal.util.AnnotationProcessorContext; import org.mapstruct.ap.internal.util.RoundContext; +import org.mapstruct.ap.internal.util.Services; +import org.mapstruct.ap.spi.AdditionalSupportedOptionsProvider; import org.mapstruct.ap.spi.TypeHierarchyErroneousException; +import static javax.lang.model.element.ElementKind.CLASS; + /** * A JSR 269 annotation {@link Processor} which generates the implementations for mapper interfaces (interfaces * annotated with {@code @Mapper}). @@ -74,9 +69,9 @@ *
  • if no error occurred, write out the model into Java source files
  • * *

    - * For reading annotation attributes, prisms as generated with help of the Hickory tool are used. These prisms allow a comfortable access to - * annotations and their attributes without depending on their class objects. + * For reading annotation attributes, gems as generated with help of Gem Tools. These gems allow comfortable access to annotations and + * their attributes without depending on their class objects. *

    * The creation of Java source files is done using the FreeMarker template engine. * Each node of the mapper model has a corresponding FreeMarker template file which provides the Java representation of @@ -87,12 +82,6 @@ * @author Gunnar Morling */ @SupportedAnnotationTypes("org.mapstruct.Mapper") -@SupportedOptions({ - MappingProcessor.SUPPRESS_GENERATOR_TIMESTAMP, - MappingProcessor.SUPPRESS_GENERATOR_VERSION_INFO_COMMENT, - MappingProcessor.UNMAPPED_TARGET_POLICY, - MappingProcessor.DEFAULT_COMPONENT_MODEL -}) public class MappingProcessor extends AbstractProcessor { /** @@ -100,12 +89,35 @@ public class MappingProcessor extends AbstractProcessor { */ private static final boolean ANNOTATIONS_CLAIMED_EXCLUSIVELY = false; - protected static final String SUPPRESS_GENERATOR_TIMESTAMP = "mapstruct.suppressGeneratorTimestamp"; - protected static final String SUPPRESS_GENERATOR_VERSION_INFO_COMMENT = - "mapstruct.suppressGeneratorVersionInfoComment"; - protected static final String UNMAPPED_TARGET_POLICY = "mapstruct.unmappedTargetPolicy"; - protected static final String DEFAULT_COMPONENT_MODEL = "mapstruct.defaultComponentModel"; - protected static final String ALWAYS_GENERATE_SERVICE_FILE = "mapstruct.alwaysGenerateServicesFile"; + // CHECKSTYLE:OFF + // Deprecated options, kept for backwards compatibility. + // They will be removed in a future release. + @Deprecated + protected static final String SUPPRESS_GENERATOR_TIMESTAMP = MappingOption.SUPPRESS_GENERATOR_TIMESTAMP.getOptionName(); + @Deprecated + protected static final String SUPPRESS_GENERATOR_VERSION_INFO_COMMENT = MappingOption.SUPPRESS_GENERATOR_VERSION_INFO_COMMENT.getOptionName(); + @Deprecated + protected static final String UNMAPPED_TARGET_POLICY = MappingOption.UNMAPPED_TARGET_POLICY.getOptionName(); + @Deprecated + protected static final String UNMAPPED_SOURCE_POLICY = MappingOption.UNMAPPED_SOURCE_POLICY.getOptionName(); + @Deprecated + protected static final String DEFAULT_COMPONENT_MODEL = MappingOption.DEFAULT_COMPONENT_MODEL.getOptionName(); + @Deprecated + protected static final String DEFAULT_INJECTION_STRATEGY = MappingOption.DEFAULT_INJECTION_STRATEGY.getOptionName(); + @Deprecated + protected static final String ALWAYS_GENERATE_SERVICE_FILE = MappingOption.ALWAYS_GENERATE_SERVICE_FILE.getOptionName(); + @Deprecated + protected static final String DISABLE_BUILDERS = MappingOption.DISABLE_BUILDERS.getOptionName(); + @Deprecated + protected static final String VERBOSE = MappingOption.VERBOSE.getOptionName(); + @Deprecated + protected static final String NULL_VALUE_ITERABLE_MAPPING_STRATEGY = MappingOption.NULL_VALUE_ITERABLE_MAPPING_STRATEGY.getOptionName(); + @Deprecated + protected static final String NULL_VALUE_MAP_MAPPING_STRATEGY = MappingOption.NULL_VALUE_MAP_MAPPING_STRATEGY.getOptionName(); + // CHECKSTYLE:ON + + private final Set additionalSupportedOptions; + private final String additionalSupportedOptionsError; private Options options; @@ -118,28 +130,43 @@ public class MappingProcessor extends AbstractProcessor { *

    * If the hierarchy of a mapper's source/target types is never completed (i.e. the missing super-types are not * generated by other processors), this mapper will not be generated; That's fine, the compiler will raise an error - * due to the inconsistent Java types used as source or target anyways. + * due to the inconsistent Java types used as source or target anyway. */ - private Set deferredMappers = new HashSet(); + private Set deferredMappers = new HashSet<>(); + + public MappingProcessor() { + Set additionalSupportedOptions; + String additionalSupportedOptionsError; + try { + additionalSupportedOptions = resolveAdditionalSupportedOptions(); + additionalSupportedOptionsError = null; + } + catch ( IllegalStateException ex ) { + additionalSupportedOptions = Collections.emptySet(); + additionalSupportedOptionsError = ex.getMessage(); + } + this.additionalSupportedOptions = additionalSupportedOptions; + this.additionalSupportedOptionsError = additionalSupportedOptionsError; + } @Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init( processingEnv ); - options = createOptions(); - annotationProcessorContext = new AnnotationProcessorContext( processingEnv.getElementUtils() ); - } - - private Options createOptions() { - String unmappedTargetPolicy = processingEnv.getOptions().get( UNMAPPED_TARGET_POLICY ); - - return new Options( - Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_TIMESTAMP ) ), - Boolean.valueOf( processingEnv.getOptions().get( SUPPRESS_GENERATOR_VERSION_INFO_COMMENT ) ), - unmappedTargetPolicy != null ? ReportingPolicyPrism.valueOf( unmappedTargetPolicy.toUpperCase() ) : null, - processingEnv.getOptions().get( DEFAULT_COMPONENT_MODEL ), - Boolean.valueOf( processingEnv.getOptions().get( ALWAYS_GENERATE_SERVICE_FILE ) ) + options = new Options( processingEnv.getOptions() ); + annotationProcessorContext = new AnnotationProcessorContext( + processingEnv.getElementUtils(), + processingEnv.getTypeUtils(), + processingEnv.getMessager(), + options.isDisableBuilders(), + options.isDisableJSpecify(), + options.isVerbose(), + resolveAdditionalOptions( processingEnv.getOptions() ) ); + + if ( additionalSupportedOptionsError != null ) { + processingEnv.getMessager().printMessage( Kind.ERROR, additionalSupportedOptionsError ); + } } @Override @@ -161,18 +188,63 @@ public boolean process(final Set annotations, final Round Set mappers = getMappers( annotations, roundEnvironment ); processMapperElements( mappers, roundContext ); } + else if ( !deferredMappers.isEmpty() ) { + // If the processing is over and there are deferred mappers it means something wrong occurred and + // MapStruct didn't generate implementations for those + for ( DeferredMapper deferredMapper : deferredMappers ) { + + TypeElement deferredMapperElement = deferredMapper.deferredMapperElement; + Element erroneousElement = deferredMapper.erroneousElement; + String erroneousElementName; + + if ( erroneousElement instanceof QualifiedNameable ) { + erroneousElementName = ( (QualifiedNameable) erroneousElement ).getQualifiedName().toString(); + } + else { + erroneousElementName = + erroneousElement != null ? erroneousElement.getSimpleName().toString() : null; + } + + // When running on Java 8 we need to fetch the deferredMapperElement again. + // Otherwise the reporting will not work properly + deferredMapperElement = annotationProcessorContext.getElementUtils() + .getTypeElement( deferredMapperElement.getQualifiedName() ); + + processingEnv.getMessager() + .printMessage( + Kind.ERROR, + "No implementation was created for " + deferredMapperElement.getSimpleName() + + " due to having a problem in the erroneous element " + erroneousElementName + "." + + " Hint: this often means that some other annotation processor was supposed to" + + " process the erroneous element. You can also enable MapStruct verbose mode by setting" + + " -Amapstruct.verbose=true as a compilation argument.", + deferredMapperElement + ); + } + + } return ANNOTATIONS_CLAIMED_EXCLUSIVELY; } + @Override + public Set getSupportedOptions() { + return Stream.concat( + Stream.of( MappingOption.values() ).map( MappingOption::getOptionName ), + additionalSupportedOptions.stream() + ) + .collect( Collectors.toSet() ); + } + /** * Gets fresh copies of all mappers deferred from previous rounds (the originals may contain references to * erroneous source/target type elements). */ private Set getAndResetDeferredMappers() { - Set deferred = new HashSet( deferredMappers.size() ); + Set deferred = new HashSet<>( deferredMappers.size() ); - for (TypeElement element : deferredMappers ) { + for ( DeferredMapper deferredMapper : deferredMappers ) { + TypeElement element = deferredMapper.deferredMapperElement; deferred.add( processingEnv.getElementUtils().getTypeElement( element.getQualifiedName() ) ); } @@ -182,7 +254,7 @@ private Set getAndResetDeferredMappers() { private Set getMappers(final Set annotations, final RoundEnvironment roundEnvironment) { - Set mapperTypes = new HashSet(); + Set mapperTypes = new HashSet<>(); for ( TypeElement annotation : annotations ) { //Indicates that the annotation's type isn't on the class path of the compiled @@ -193,12 +265,12 @@ private Set getMappers(final Set annotations try { Set annotatedMappers = roundEnvironment.getElementsAnnotatedWith( annotation ); - for (Element mapperElement : annotatedMappers) { + for ( Element mapperElement : annotatedMappers ) { TypeElement mapperTypeElement = asTypeElement( mapperElement ); // on some JDKs, RoundEnvironment.getElementsAnnotatedWith( ... ) returns types with // annotations unknown to the compiler, even though they are not declared Mappers - if ( mapperTypeElement != null && MapperPrism.getInstanceOn( mapperTypeElement ) != null ) { + if ( mapperTypeElement != null && MapperGem.instanceOn( mapperTypeElement ) != null ) { mapperTypes.add( mapperTypeElement ); } } @@ -219,14 +291,28 @@ private void processMapperElements(Set mapperElements, RoundContext // note that this assumes that a new source file is created for each mapper which must not // necessarily be the case, e.g. in case of several mapper interfaces declared as inner types // of one outer interface + List tst = mapperElement.getEnclosedElements(); ProcessorContext context = new DefaultModelElementProcessorContext( - processingEnv, options, roundContext + processingEnv, + options, + roundContext, + getDeclaredTypesNotToBeImported( mapperElement ), + mapperElement ); processMapperTypeElement( context, mapperElement ); } catch ( TypeHierarchyErroneousException thie ) { - deferredMappers.add( mapperElement ); + TypeMirror erroneousType = thie.getType(); + Element erroneousElement = erroneousType != null ? roundContext.getAnnotationProcessorContext() + .getTypeUtils() + .asElement( erroneousType ) : null; + if ( options.isVerbose() ) { + processingEnv.getMessager().printMessage( + Kind.NOTE, "MapStruct: referred types not available (yet), deferring mapper: " + + mapperElement ); + } + deferredMappers.add( new DeferredMapper( mapperElement, erroneousElement ) ); } catch ( Throwable t ) { handleUncaughtError( mapperElement, t ); @@ -235,11 +321,19 @@ private void processMapperElements(Set mapperElements, RoundContext } } + private Map getDeclaredTypesNotToBeImported(TypeElement element) { + return element.getEnclosedElements().stream() + .filter( e -> CLASS.equals( e.getKind() ) ) + .map( Element::getSimpleName ) + .map( Name::toString ) + .collect( Collectors.toMap( k -> k, v -> element.getQualifiedName().toString() + "." + v ) ); + } + private void handleUncaughtError(Element element, Throwable thrown) { StringWriter sw = new StringWriter(); thrown.printStackTrace( new PrintWriter( sw ) ); - String reportableStacktrace = sw.toString().replace( System.getProperty( "line.separator" ), " " ); + String reportableStacktrace = sw.toString().replace( System.lineSeparator( ), " " ); processingEnv.getMessager().printMessage( Kind.ERROR, "Internal error in the mapping processor: " + reportableStacktrace, element ); @@ -282,7 +376,7 @@ private R process(ProcessorContext context, ModelElementProcessor p /** * Retrieves all model element processors, ordered by their priority value - * (with the method retrieval processor having the lowest priority value (1) + * (with the method retrieval processor having the lowest priority value (1)) * and the code generation processor the highest priority value. * * @return A list with all model element processors. @@ -296,20 +390,20 @@ private R process(ProcessorContext context, ModelElementProcessor p MappingProcessor.class.getClassLoader() ) .iterator(); - List> processors = new ArrayList>(); + List> processors = new ArrayList<>(); while ( processorIterator.hasNext() ) { processors.add( processorIterator.next() ); } - Collections.sort( processors, new ProcessorComparator() ); + processors.sort( new ProcessorComparator() ); return processors; } private TypeElement asTypeElement(Element element) { return element.accept( - new ElementKindVisitor6() { + new ElementKindVisitor8() { @Override public TypeElement visitTypeAsInterface(TypeElement e, Void p) { return e; @@ -324,14 +418,63 @@ public TypeElement visitTypeAsClass(TypeElement e, Void p) { ); } + /** + * Fetch the additional supported options provided by the SPI {@link AdditionalSupportedOptionsProvider}. + * + * @return the additional supported options + */ + private static Set resolveAdditionalSupportedOptions() { + Set additionalSupportedOptions = null; + for ( AdditionalSupportedOptionsProvider optionsProvider : + Services.all( AdditionalSupportedOptionsProvider.class ) ) { + if ( additionalSupportedOptions == null ) { + additionalSupportedOptions = new HashSet<>(); + } + Set providerOptions = optionsProvider.getAdditionalSupportedOptions(); + + for ( String providerOption : providerOptions ) { + // Ensure additional options are not in the mapstruct namespace + if ( providerOption.startsWith( "mapstruct" ) ) { + throw new IllegalStateException( + "Additional SPI options cannot start with \"mapstruct\". Provider " + optionsProvider + + " provided option " + providerOption ); + } + additionalSupportedOptions.add( providerOption ); + } + + } + + return additionalSupportedOptions == null ? Collections.emptySet() : additionalSupportedOptions; + } + private static class ProcessorComparator implements Comparator> { @Override public int compare(ModelElementProcessor o1, ModelElementProcessor o2) { - return - o1.getPriority() < o2.getPriority() ? -1 : - o1.getPriority() == o2.getPriority() ? 0 : - 1; + return Integer.compare( o1.getPriority(), o2.getPriority() ); } } + + private static class DeferredMapper { + + private final TypeElement deferredMapperElement; + private final Element erroneousElement; + + private DeferredMapper(TypeElement deferredMapperElement, Element erroneousElement) { + this.deferredMapperElement = deferredMapperElement; + this.erroneousElement = erroneousElement; + } + } + + /** + * Filters only the options belonging to the declared additional supported options. + * + * @param options all processor environment options + * @return filtered options + */ + private Map resolveAdditionalOptions(Map options) { + return options.entrySet().stream() + .filter( entry -> additionalSupportedOptions.contains( entry.getKey() ) ) + .collect( Collectors.toMap( Map.Entry::getKey, Map.Entry::getValue ) ); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJavaTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJavaTimeToStringConversion.java index 093e1511f4..3503a0e274 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJavaTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJavaTimeToStringConversion.java @@ -1,29 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; +import java.time.format.DateTimeFormatter; +import java.util.List; import java.util.Set; import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.FieldReference; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.util.Collections; -import org.mapstruct.ap.internal.util.JavaTimeConstants; import org.mapstruct.ap.internal.util.Strings; /** @@ -32,15 +21,15 @@ *

    *

    * In general each type comes with a "parse" method to convert a string to this particular type. - * For formatting a dedicated instance of {@link java.time.format.DateTimeFormatter} is used. + * For formatting a dedicated instance of {@link DateTimeFormatter} is used. *

    *

    * If no date format for mapping is specified predefined ISO* formatters from - * {@link java.time.format.DateTimeFormatter} are used. + * {@link DateTimeFormatter} are used. *

    *

    - * An overview of date and time types shipped with Java 8 can be found at - * http://docs.oracle.com/javase/tutorial/datetime/iso/index.html. + * An overview of date and time types shipped with Java 8 can be found at the + * Standard Calendar Tutorial *

    */ public abstract class AbstractJavaTimeToStringConversion extends SimpleConversion { @@ -51,10 +40,8 @@ protected String getToExpression(ConversionContext conversionContext) { } private String dateTimeFormatter(ConversionContext conversionContext) { - if ( !Strings.isEmpty( conversionContext.getDateFormat() ) ) { - return ConversionUtils.dateTimeFormatter( conversionContext ) - + ".ofPattern( \"" + conversionContext.getDateFormat() - + "\" )"; + if ( Strings.isNotEmpty( conversionContext.getDateFormat() ) ) { + return GetDateTimeFormatterField.getDateTimeFormatterFieldName( conversionContext.getDateFormat() ); } else { return ConversionUtils.dateTimeFormatter( conversionContext ) + "." + defaultFormatterSuffix(); @@ -66,7 +53,7 @@ private String dateTimeFormatter(ConversionContext conversionContext) { @Override protected String getFromExpression(ConversionContext conversionContext) { // See http://docs.oracle.com/javase/tutorial/datetime/iso/format.html for how to parse Dates - return new StringBuilder().append( conversionContext.getTargetType().getReferenceName() ) + return new StringBuilder().append( conversionContext.getTargetType().createReferenceName() ) .append( ".parse( " ) .append( parametersListForParsing( conversionContext ) ) .append( " )" ).toString(); @@ -85,7 +72,7 @@ private String parametersListForParsing(ConversionContext conversionContext) { @Override protected Set getToConversionImportTypes(ConversionContext conversionContext) { return Collections.asSet( - conversionContext.getTypeFactory().getType( JavaTimeConstants.DATE_TIME_FORMATTER_FQN ) + conversionContext.getTypeFactory().getType( DateTimeFormatter.class ) ); } @@ -94,11 +81,22 @@ protected Set getFromConversionImportTypes(ConversionContext conversionCon if ( !Strings.isEmpty( conversionContext.getDateFormat() ) ) { return Collections.asSet( conversionContext.getTargetType(), - conversionContext.getTypeFactory().getType( JavaTimeConstants.DATE_TIME_FORMATTER_FQN ) + conversionContext.getTypeFactory().getType( DateTimeFormatter.class ) ); } return Collections.asSet( conversionContext.getTargetType() ); } + @Override + public List getRequiredHelperFields(ConversionContext conversionContext) { + if ( Strings.isNotEmpty( conversionContext.getDateFormat() ) ) { + return java.util.Collections.singletonList( + new GetDateTimeFormatterField( + conversionContext.getTypeFactory(), + conversionContext.getDateFormat() ) ); + } + + return super.getRequiredHelperFields( conversionContext ); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJodaTypeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJodaTypeToStringConversion.java index e6c9b855fa..c0a3d56481 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJodaTypeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractJodaTypeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -26,9 +13,9 @@ import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.util.JodaTimeConstants; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.dateTimeFormat; import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Base class for conversions between Joda-Time types and String. diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractNumberToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractNumberToStringConversion.java index 43f8af8416..99649a9a37 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractNumberToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/AbstractNumberToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToBigIntegerConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToBigIntegerConversion.java index 080c6e0887..6268371480 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToBigIntegerConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToBigIntegerConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -25,8 +12,8 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigDecimal; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigDecimal} and {@link BigInteger}. @@ -51,4 +38,5 @@ public String getFromExpression(ConversionContext conversionContext) { protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return asSet( conversionContext.getTypeFactory().getType( BigDecimal.class ) ); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToPrimitiveConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToPrimitiveConversion.java index 851070c540..ff50b910cd 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToPrimitiveConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToPrimitiveConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -24,8 +11,8 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigDecimal; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigDecimal} and native number types. @@ -37,10 +24,6 @@ public class BigDecimalToPrimitiveConversion extends SimpleConversion { private final Class targetType; public BigDecimalToPrimitiveConversion(Class targetType) { - if ( !targetType.isPrimitive() ) { - throw new IllegalArgumentException( targetType + " is no primitive type." ); - } - this.targetType = targetType; } @@ -58,4 +41,5 @@ public String getFromExpression(ConversionContext conversionContext) { protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return asSet( conversionContext.getTypeFactory().getType( BigDecimal.class ) ); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToStringConversion.java index d423dc8662..384013a7b3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -27,8 +14,9 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigDecimal; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigDecimal} and {@link String}. @@ -58,7 +46,7 @@ public String getToExpression(ConversionContext conversionContext) { public String getFromExpression(ConversionContext conversionContext) { if ( requiresDecimalFormat( conversionContext ) ) { StringBuilder sb = new StringBuilder(); - sb.append( "(" + bigDecimal( conversionContext ) + ") " ); + sb.append( "(" ).append( bigDecimal( conversionContext ) ).append( ") " ); appendDecimalFormatter( sb, conversionContext ); sb.append( ".parse( )" ); return sb.toString(); @@ -75,20 +63,33 @@ protected Set getFromConversionImportTypes(ConversionContext conversionCon @Override public List getRequiredHelperMethods(ConversionContext conversionContext) { - List helpers = new ArrayList(); + List helpers = new ArrayList<>(); if ( conversionContext.getNumberFormat() != null ) { - helpers.add( new CreateDecimalFormat( conversionContext.getTypeFactory() ) ); + helpers.add( new CreateDecimalFormat( + conversionContext.getTypeFactory(), + conversionContext.getLocale() != null + ) ); } return helpers; } private void appendDecimalFormatter(StringBuilder sb, ConversionContext conversionContext) { - sb.append( "createDecimalFormat( " ); + boolean withLocale = conversionContext.getLocale() != null; + sb.append( "createDecimalFormat" ); + if ( withLocale ) { + sb.append( "WithLocale" ); + } + sb.append( "( " ); if ( conversionContext.getNumberFormat() != null ) { sb.append( "\"" ); sb.append( conversionContext.getNumberFormat() ); sb.append( "\"" ); } + if ( withLocale ) { + sb.append( ", " ).append( locale( conversionContext ) ).append( ".forLanguageTag( \"" ); + sb.append( conversionContext.getLocale() ); + sb.append( "\" )" ); + } sb.append( " )" ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToWrapperConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToWrapperConversion.java index 0068a27d2a..ef5a3175e7 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToWrapperConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigDecimalToWrapperConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -25,8 +12,8 @@ import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.util.NativeTypes; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigDecimal; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigDecimal} and wrappers of native number types. @@ -38,10 +25,6 @@ public class BigDecimalToWrapperConversion extends SimpleConversion { private final Class targetType; public BigDecimalToWrapperConversion(Class targetType) { - if ( targetType.isPrimitive() ) { - throw new IllegalArgumentException( targetType + " is a primitive type." ); - } - this.targetType = NativeTypes.getPrimitiveType( targetType ); } @@ -59,4 +42,5 @@ public String getFromExpression(ConversionContext conversionContext) { protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return asSet( conversionContext.getTypeFactory().getType( BigDecimal.class ) ); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToPrimitiveConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToPrimitiveConversion.java index 464f983825..75c3647bad 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToPrimitiveConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToPrimitiveConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -24,8 +11,8 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigInteger; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigInteger} and native number types. @@ -37,10 +24,6 @@ public class BigIntegerToPrimitiveConversion extends SimpleConversion { private final Class targetType; public BigIntegerToPrimitiveConversion(Class targetType) { - if ( !targetType.isPrimitive() ) { - throw new IllegalArgumentException( targetType + " is no primitive type." ); - } - this.targetType = targetType; } @@ -62,4 +45,5 @@ public String getFromExpression(ConversionContext conversionContext) { protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return asSet( conversionContext.getTypeFactory().getType( BigInteger.class ) ); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToStringConversion.java index 034d191227..dc3bd29cd8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -28,9 +15,10 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigDecimal; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigInteger; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigInteger} and {@link String}. @@ -60,7 +48,7 @@ public String getToExpression(ConversionContext conversionContext) { public String getFromExpression(ConversionContext conversionContext) { if ( requiresDecimalFormat( conversionContext ) ) { StringBuilder sb = new StringBuilder(); - sb.append( "( (" + bigDecimal( conversionContext ) + ") " ); + sb.append( "( (" ).append( bigDecimal( conversionContext ) ).append( ") " ); appendDecimalFormatter( sb, conversionContext ); sb.append( ".parse( )" ); sb.append( " ).toBigInteger()" ); @@ -83,20 +71,33 @@ protected Set getFromConversionImportTypes(ConversionContext conversionCon @Override public List getRequiredHelperMethods(ConversionContext conversionContext) { - List helpers = new ArrayList(); + List helpers = new ArrayList<>(); if ( conversionContext.getNumberFormat() != null ) { - helpers.add( new CreateDecimalFormat( conversionContext.getTypeFactory() ) ); + helpers.add( new CreateDecimalFormat( + conversionContext.getTypeFactory(), + conversionContext.getLocale() != null + ) ); } return helpers; } private void appendDecimalFormatter(StringBuilder sb, ConversionContext conversionContext) { - sb.append( "createDecimalFormat( " ); + boolean withLocale = conversionContext.getLocale() != null; + sb.append( "createDecimalFormat" ); + if ( withLocale ) { + sb.append( "WithLocale" ); + } + sb.append( "( " ); if ( conversionContext.getNumberFormat() != null ) { sb.append( "\"" ); sb.append( conversionContext.getNumberFormat() ); sb.append( "\"" ); } + if ( withLocale ) { + sb.append( ", " ).append( locale( conversionContext ) ).append( ".forLanguageTag( \"" ); + sb.append( conversionContext.getLocale() ); + sb.append( "\" )" ); + } sb.append( " )" ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToWrapperConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToWrapperConversion.java index 5ec50cf246..b3aa5dc6f2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToWrapperConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/BigIntegerToWrapperConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -25,8 +12,8 @@ import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.util.NativeTypes; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.bigInteger; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link BigInteger} and wrappers of native number types. @@ -38,10 +25,6 @@ public class BigIntegerToWrapperConversion extends SimpleConversion { private final Class targetType; public BigIntegerToWrapperConversion(Class targetType) { - if ( targetType.isPrimitive() ) { - throw new IllegalArgumentException( targetType + " is a primitive type." ); - } - this.targetType = NativeTypes.getPrimitiveType( targetType ); } @@ -64,4 +47,5 @@ public String getFromExpression(ConversionContext conversionContext) { protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return asSet( conversionContext.getTypeFactory().getType( BigInteger.class ) ); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharToStringConversion.java index 0b0e66f778..fa6434b582 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharWrapperToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharWrapperToStringConversion.java index 17564f6613..5dd6d6bf73 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharWrapperToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CharWrapperToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionProvider.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionProvider.java index 574f73dcae..b392281bf4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionProvider.java @@ -1,28 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; +import java.util.Collections; import java.util.List; + +import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.TypeConversion; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ConversionContext; -import org.mapstruct.ap.internal.model.HelperMethod; +import org.mapstruct.ap.internal.model.common.FieldReference; /** * Implementations create inline {@link TypeConversion}s such as @@ -56,9 +46,23 @@ public interface ConversionProvider { Assignment from(ConversionContext conversionContext); /** + * Retrieves any helper methods required for creating the conversion. + * * @param conversionContext ConversionContext providing optional information required for creating the conversion. * * @return any helper methods when required. */ List getRequiredHelperMethods(ConversionContext conversionContext); + + /** + * Retrieves any fields required for creating the conversion. + * + * @param conversionContext ConversionContext providing optional information required for creating the conversion. + * + * @return any fields when required. + */ + default List getRequiredHelperFields(ConversionContext conversionContext) { + return Collections.emptyList(); + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionUtils.java index f295fa80bc..e014e30f27 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionUtils.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ConversionUtils.java @@ -1,34 +1,29 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; import java.math.BigDecimal; import java.math.BigInteger; +import java.net.URI; import java.sql.Time; import java.sql.Timestamp; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Currency; import java.util.Locale; +import java.util.UUID; import org.mapstruct.ap.internal.model.common.ConversionContext; -import org.mapstruct.ap.internal.util.JavaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants; /** @@ -50,7 +45,7 @@ private ConversionUtils() { * @return Name or fully-qualified name. */ private static String typeReferenceName(ConversionContext conversionContext, String canonicalName) { - return conversionContext.getTypeFactory().getType( canonicalName ).getReferenceName(); + return conversionContext.getTypeFactory().getType( canonicalName ).createReferenceName(); } /** @@ -62,7 +57,7 @@ private static String typeReferenceName(ConversionContext conversionContext, Str * @return Name or fully-qualified name. */ private static String typeReferenceName(ConversionContext conversionContext, Class type) { - return conversionContext.getTypeFactory().getType( type ).getReferenceName(); + return conversionContext.getTypeFactory().getType( type ).createReferenceName(); } /** @@ -183,7 +178,7 @@ public static String date(ConversionContext conversionContext) { * @return Name or fully-qualified name. */ public static String zoneOffset(ConversionContext conversionContext) { - return typeReferenceName( conversionContext, JavaTimeConstants.ZONE_OFFSET_FQN ); + return typeReferenceName( conversionContext, ZoneOffset.class ); } /** @@ -194,7 +189,18 @@ public static String zoneOffset(ConversionContext conversionContext) { * @return Name or fully-qualified name. */ public static String zoneId(ConversionContext conversionContext) { - return typeReferenceName( conversionContext, JavaTimeConstants.ZONE_ID_FQN ); + return typeReferenceName( conversionContext, ZoneId.class ); + } + + /** + * Name for {@link java.time.LocalDate}. + * + * @param conversionContext Conversion context + * + * @return Name or fully-qualified name. + */ + public static String localDate(ConversionContext conversionContext) { + return typeReferenceName( conversionContext, LocalDate.class ); } /** @@ -205,7 +211,7 @@ public static String zoneId(ConversionContext conversionContext) { * @return Name or fully-qualified name. */ public static String localDateTime(ConversionContext conversionContext) { - return typeReferenceName( conversionContext, JavaTimeConstants.LOCAL_DATE_TIME_FQN ); + return typeReferenceName( conversionContext, LocalDateTime.class ); } /** @@ -216,7 +222,7 @@ public static String localDateTime(ConversionContext conversionContext) { * @return Name or fully-qualified name. */ public static String zonedDateTime(ConversionContext conversionContext) { - return typeReferenceName( conversionContext, JavaTimeConstants.ZONED_DATE_TIME_FQN ); + return typeReferenceName( conversionContext, ZonedDateTime.class ); } /** @@ -227,7 +233,7 @@ public static String zonedDateTime(ConversionContext conversionContext) { * @return Name or fully-qualified name. */ public static String dateTimeFormatter(ConversionContext conversionContext) { - return typeReferenceName( conversionContext, JavaTimeConstants.DATE_TIME_FORMATTER_FQN ); + return typeReferenceName( conversionContext, DateTimeFormatter.class ); } /** @@ -240,4 +246,49 @@ public static String dateTimeFormatter(ConversionContext conversionContext) { public static String dateTimeFormat(ConversionContext conversionContext) { return typeReferenceName( conversionContext, JodaTimeConstants.DATE_TIME_FORMAT_FQN ); } + + /** + * Name for {@link java.lang.StringBuilder}. + * + * @param conversionContext Conversion context + * + * @return Name or fully-qualified name. + */ + public static String stringBuilder(ConversionContext conversionContext) { + return typeReferenceName( conversionContext, StringBuilder.class ); + } + + /** + * Name for {@link java.util.UUID}. + * + * @param conversionContext Conversion context + * + * @return Name or fully-qualified name. + */ + public static String uuid(ConversionContext conversionContext) { + return typeReferenceName( conversionContext, UUID.class ); + } + + /** + * Name for {@link java.net.URI}. + * + * @param conversionContext Conversion context + * + * @return Name or fully-qualified name. + */ + public static String uri(ConversionContext conversionContext) { + return typeReferenceName( conversionContext, URI.class ); + } + + /** + * Name for {@link java.text.DecimalFormatSymbols}. + * + * @param conversionContext Conversion context + * + * @return Name or fully-qualified name. + */ + public static String decimalFormatSymbols(ConversionContext conversionContext) { + return typeReferenceName( conversionContext, DecimalFormatSymbols.class ); + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/Conversions.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/Conversions.java index 239c060b3d..6e1f2c03aa 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/Conversions.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/Conversions.java @@ -1,42 +1,39 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; -import static org.mapstruct.ap.internal.conversion.ReverseConversion.reverse; - import java.math.BigDecimal; import java.math.BigInteger; +import java.net.URI; +import java.net.URL; import java.sql.Time; import java.sql.Timestamp; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.OffsetDateTime; +import java.time.Period; +import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Currency; import java.util.Date; import java.util.HashMap; +import java.util.Locale; import java.util.Map; - -import javax.lang.model.util.Elements; +import java.util.Objects; +import java.util.UUID; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.util.JavaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import static org.mapstruct.ap.internal.conversion.ReverseConversion.inverse; + /** * Holds built-in {@link ConversionProvider}s such as from {@code int} to {@code String}. * @@ -44,16 +41,18 @@ */ public class Conversions { - private final Map conversions = new HashMap(); + private final Map conversions = new HashMap<>(); private final Type enumType; private final Type stringType; + private final Type integerType; private final TypeFactory typeFactory; - public Conversions(Elements elementUtils, TypeFactory typeFactory) { + public Conversions(TypeFactory typeFactory) { this.typeFactory = typeFactory; this.enumType = typeFactory.getType( Enum.class ); this.stringType = typeFactory.getType( String.class ); + this.integerType = typeFactory.getType( Integer.class ); //native types <> native types, including wrappers registerNativeTypeConversion( byte.class, Byte.class ); @@ -181,8 +180,9 @@ public Conversions(Elements elementUtils, TypeFactory typeFactory) { registerToStringConversion( Boolean.class ); register( char.class, String.class, new CharToStringConversion() ); register( Character.class, String.class, new CharWrapperToStringConversion() ); - register( BigInteger.class, String.class, new BigIntegerToStringConversion( ) ); - register( BigDecimal.class, String.class, new BigDecimalToStringConversion( ) ); + register( BigInteger.class, String.class, new BigIntegerToStringConversion() ); + register( BigDecimal.class, String.class, new BigDecimalToStringConversion() ); + register( StringBuilder.class, String.class, new StringBuilderToStringConversion() ); registerJodaConversions(); @@ -190,14 +190,20 @@ public Conversions(Elements elementUtils, TypeFactory typeFactory) { //misc. register( Enum.class, String.class, new EnumStringConversion() ); + register( Enum.class, Integer.class, new EnumToIntegerConversion() ); + register( Enum.class, int.class, new EnumToIntegerConversion() ); register( Date.class, String.class, new DateToStringConversion() ); register( BigDecimal.class, BigInteger.class, new BigDecimalToBigIntegerConversion() ); - register( Date.class, Time.class, new DateToSqlTimeConversion() ); - register( Date.class, java.sql.Date.class, new DateToSqlDateConversion() ); - register( Date.class, Timestamp.class, new DateToSqlTimestampConversion() ); + + registerJavaTimeSqlConversions(); // java.util.Currency <~> String register( Currency.class, String.class, new CurrencyToStringConversion() ); + + register( UUID.class, String.class, new UUIDToStringConversion() ); + register( Locale.class, String.class, new LocaleToStringConversion() ); + + registerJavaNetConversions(); } private void registerJodaConversions() { @@ -221,40 +227,58 @@ private void registerJodaConversions() { } private void registerJava8TimeConversions() { - if ( !isJava8TimeAvailable() ) { - return; - } // Java 8 time to String - register( JavaTimeConstants.ZONED_DATE_TIME_FQN, String.class, new JavaZonedDateTimeToStringConversion() ); - register( JavaTimeConstants.LOCAL_DATE_FQN, String.class, new JavaLocalDateToStringConversion() ); - register( JavaTimeConstants.LOCAL_DATE_TIME_FQN, String.class, new JavaLocalDateTimeToStringConversion() ); - register( JavaTimeConstants.LOCAL_TIME_FQN, String.class, new JavaLocalTimeToStringConversion() ); + register( ZonedDateTime.class, String.class, new JavaZonedDateTimeToStringConversion() ); + register( LocalDate.class, String.class, new JavaLocalDateToStringConversion() ); + register( LocalDateTime.class, String.class, new JavaLocalDateTimeToStringConversion() ); + register( LocalTime.class, String.class, new JavaLocalTimeToStringConversion() ); + register( Instant.class, String.class, new StaticParseToStringConversion() ); + register( Period.class, String.class, new StaticParseToStringConversion() ); + register( Duration.class, String.class, new StaticParseToStringConversion() ); + + // Java 8 time to Date + register( ZonedDateTime.class, Date.class, new JavaZonedDateTimeToDateConversion() ); + register( LocalDateTime.class, Date.class, new JavaLocalDateTimeToDateConversion() ); + register( LocalDate.class, Date.class, new JavaLocalDateToDateConversion() ); + register( Instant.class, Date.class, new JavaInstantToDateConversion() ); + + // Java 8 time + register( LocalDateTime.class, LocalDate.class, new JavaLocalDateTimeToLocalDateConversion() ); + register( ZonedDateTime.class, LocalDateTime.class, new JavaZonedDateTimeToLocalDateTimeConversion() ); + register( OffsetDateTime.class, LocalDateTime.class, new JavaOffsetDateTimeToLocalDateTimeConversion() ); + + register( ZonedDateTime.class, Instant.class, new JavaZonedDateTimeToInstantConversion() ); + register( OffsetDateTime.class, Instant.class, new JavaOffsetDateTimeToInstantConversion() ); + } - // Java 8 to Date - register( JavaTimeConstants.ZONED_DATE_TIME_FQN, Date.class, new JavaZonedDateTimeToDateConversion() ); - register( JavaTimeConstants.LOCAL_DATE_TIME_FQN, Date.class, new JavaLocalDateTimeToDateConversion() ); - register( JavaTimeConstants.LOCAL_DATE_FQN, Date.class, new JavaLocalDateToDateConversion() ); + private void registerJavaTimeSqlConversions() { + if ( isJavaSqlAvailable() ) { + register( LocalDate.class, java.sql.Date.class, new JavaLocalDateToSqlDateConversion() ); + register( Date.class, Time.class, new DateToSqlTimeConversion() ); + register( Date.class, java.sql.Date.class, new DateToSqlDateConversion() ); + register( Date.class, Timestamp.class, new DateToSqlTimestampConversion() ); + } } private boolean isJodaTimeAvailable() { return typeFactory.isTypeAvailable( JodaTimeConstants.DATE_TIME_FQN ); } - private boolean isJava8TimeAvailable() { - return typeFactory.isTypeAvailable( JavaTimeConstants.ZONED_DATE_TIME_FQN ); + private boolean isJavaSqlAvailable() { + return typeFactory.isTypeAvailable( "java.sql.Date" ); } private void registerNativeTypeConversion(Class sourceType, Class targetType) { if ( sourceType.isPrimitive() && targetType.isPrimitive() ) { register( sourceType, targetType, new PrimitiveToPrimitiveConversion( sourceType ) ); } - else if ( sourceType.isPrimitive() && !targetType.isPrimitive() ) { + else if ( sourceType.isPrimitive() ) { register( sourceType, targetType, new PrimitiveToWrapperConversion( sourceType, targetType ) ); } - else if ( !sourceType.isPrimitive() && targetType.isPrimitive() ) { - register( sourceType, targetType, reverse( new PrimitiveToWrapperConversion( targetType, sourceType ) ) ); + else if ( targetType.isPrimitive() ) { + register( sourceType, targetType, inverse( new PrimitiveToWrapperConversion( targetType, sourceType ) ) ); } else { register( sourceType, targetType, new WrapperToWrapperConversion( sourceType, targetType ) ); @@ -288,12 +312,23 @@ private void registerBigDecimalConversion(Class targetType) { } } + private void registerJavaNetConversions() { + if ( isJavaNetAvailable() ) { + register( URI.class, String.class, new URIToStringConversion() ); + register( URL.class, String.class, new URLToStringConversion() ); + } + } + + private boolean isJavaNetAvailable() { + return typeFactory.isTypeAvailable( "java.net.URL" ); + } + private void register(Class sourceClass, Class targetClass, ConversionProvider conversion) { Type sourceType = typeFactory.getType( sourceClass ); Type targetType = typeFactory.getType( targetClass ); conversions.put( new Key( sourceType, targetType ), conversion ); - conversions.put( new Key( targetType, sourceType ), reverse( conversion ) ); + conversions.put( new Key( targetType, sourceType ), inverse( conversion ) ); } private void register(String sourceTypeName, Class targetClass, ConversionProvider conversion) { @@ -301,14 +336,55 @@ private void register(String sourceTypeName, Class targetClass, ConversionPro Type targetType = typeFactory.getType( targetClass ); conversions.put( new Key( sourceType, targetType ), conversion ); - conversions.put( new Key( targetType, sourceType ), reverse( conversion ) ); + conversions.put( new Key( targetType, sourceType ), inverse( conversion ) ); } public ConversionProvider getConversion(Type sourceType, Type targetType) { - if ( sourceType.isEnumType() && targetType.equals( stringType ) ) { + if ( sourceType.isOptionalType() ) { + if ( targetType.isOptionalType() ) { + // We cannot convert optional to optional + return null; + } + Type sourceBaseType = sourceType.getOptionalBaseType(); + if ( sourceBaseType.equals( targetType ) ) { + // Optional -> Type + return TypeToOptionalConversion.OPTIONAL_TO_TYPE_CONVERSION; + } + + ConversionProvider conversionProvider = getInternalConversion( sourceBaseType, targetType ); + if ( conversionProvider != null ) { + return inverse( new OptionalWrapperConversionProvider( conversionProvider ) ); + } + + } + else if ( targetType.isOptionalType() ) { + // Type -> Optional + Type targetBaseType = targetType.getOptionalBaseType(); + if ( targetBaseType.equals( sourceType ) ) { + return TypeToOptionalConversion.TYPE_TO_OPTIONAL_CONVERSION; + } + ConversionProvider conversionProvider = getInternalConversion( sourceType, targetBaseType ); + if ( conversionProvider != null ) { + return new OptionalWrapperConversionProvider( conversionProvider ); + } + return null; + + } + + return getInternalConversion( sourceType, targetType ); + } + + private ConversionProvider getInternalConversion(Type sourceType, Type targetType) { + if ( sourceType.isEnumType() && + ( targetType.equals( stringType ) || + targetType.getBoxedEquivalent().equals( integerType ) ) + ) { sourceType = enumType; } - else if ( targetType.isEnumType() && sourceType.equals( stringType ) ) { + else if ( targetType.isEnumType() && + ( sourceType.equals( stringType ) || + sourceType.getBoxedEquivalent().equals( integerType ) ) + ) { targetType = enumType; } @@ -351,23 +427,12 @@ public boolean equals(Object obj) { return false; } Key other = (Key) obj; - if ( sourceType == null ) { - if ( other.sourceType != null ) { - return false; - } - } - else if ( !sourceType.equals( other.sourceType ) ) { - return false; - } - if ( targetType == null ) { - if ( other.targetType != null ) { - return false; - } - } - else if ( !targetType.equals( other.targetType ) ) { + + if ( !Objects.equals( sourceType, other.sourceType ) ) { return false; } - return true; + + return Objects.equals( targetType, other.targetType ); } } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.java index d881a9fc1f..d1b49cff69 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.java @@ -1,33 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; import java.util.Set; import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.model.source.MappingOptions; +import org.mapstruct.ap.internal.model.source.MappingMethodOptions; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * HelperMethod that creates a {@link java.text.DecimalFormat} @@ -40,13 +31,30 @@ public class CreateDecimalFormat extends HelperMethod { private final Parameter parameter; + private final Parameter localeParameter; private final Type returnType; private final Set importTypes; - public CreateDecimalFormat(TypeFactory typeFactory) { + public CreateDecimalFormat(TypeFactory typeFactory, boolean withLocale) { this.parameter = new Parameter( "numberFormat", typeFactory.getType( String.class ) ); + this.localeParameter = withLocale ? new Parameter( "locale", typeFactory.getType( Locale.class ) ) : null; this.returnType = typeFactory.getType( DecimalFormat.class ); - this.importTypes = asSet( parameter.getType(), returnType ); + if ( withLocale ) { + this.importTypes = asSet( + parameter.getType(), + returnType, + typeFactory.getType( DecimalFormatSymbols.class ), + typeFactory.getType( Locale.class ) + ); + } + else { + this.importTypes = asSet( parameter.getType(), returnType ); + } + } + + @Override + public String getName() { + return localeParameter == null ? "createDecimalFormat" : "createDecimalFormatWithLocale"; } @Override @@ -65,7 +73,20 @@ public Type getReturnType() { } @Override - public MappingOptions getMappingOptions() { - return MappingOptions.empty(); + public MappingMethodOptions getOptions() { + return MappingMethodOptions.empty(); + } + + @Override + public String describe() { + return null; + } + + @Override + public List getParameters() { + if ( localeParameter == null ) { + return super.getParameters(); + } + return Arrays.asList( getParameter(), localeParameter ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CurrencyToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CurrencyToStringConversion.java index 7675370a2e..3f32994734 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/CurrencyToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/CurrencyToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -28,6 +15,8 @@ import static org.mapstruct.ap.internal.conversion.ConversionUtils.currency; /** + * Conversion between {@link Currency} and {@link String}. + * * @author Darren Rambaud */ public class CurrencyToStringConversion extends SimpleConversion { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlDateConversion.java index 5e9d3bc6b8..bc2aae7305 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlDateConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlDateConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimeConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimeConversion.java index 9407131728..ef892273e3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimeConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimeConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimestampConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimestampConversion.java index 7086b2fc07..cba40e7c5e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimestampConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToSqlTimestampConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToStringConversion.java index 624c7ab4f4..35c7f88d74 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/DateToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -23,6 +10,8 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import java.util.Locale; +import java.util.Set; import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.TypeConversion; @@ -30,9 +19,9 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static java.util.Arrays.asList; -import static org.mapstruct.ap.internal.util.Collections.asSet; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; import static org.mapstruct.ap.internal.conversion.ConversionUtils.simpleDateFormat; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@link String} and {@link Date}. @@ -43,16 +32,16 @@ public class DateToStringConversion implements ConversionProvider { @Override public Assignment to(ConversionContext conversionContext) { - return new TypeConversion( asSet( conversionContext.getTypeFactory().getType( SimpleDateFormat.class ) ), - Collections.emptyList(), + return new TypeConversion( getImportTypes( conversionContext ), + Collections.emptyList(), getConversionExpression( conversionContext, "format" ) ); } @Override public Assignment from(ConversionContext conversionContext) { - return new TypeConversion( asSet( conversionContext.getTypeFactory().getType( SimpleDateFormat.class ) ), - asList( conversionContext.getTypeFactory().getType( ParseException.class ) ), + return new TypeConversion( getImportTypes( conversionContext ), + Collections.singletonList( conversionContext.getTypeFactory().getType( ParseException.class ) ), getConversionExpression( conversionContext, "parse" ) ); } @@ -62,6 +51,17 @@ public List getRequiredHelperMethods(ConversionContext conversionC return Collections.emptyList(); } + private Set getImportTypes(ConversionContext conversionContext) { + if ( conversionContext.getLocale() == null ) { + return Collections.singleton( conversionContext.getTypeFactory().getType( SimpleDateFormat.class ) ); + } + + return asSet( + conversionContext.getTypeFactory().getType( SimpleDateFormat.class ), + conversionContext.getTypeFactory().getType( Locale.class ) + ); + } + private String getConversionExpression(ConversionContext conversionContext, String method) { StringBuilder conversionString = new StringBuilder( "new " ); conversionString.append( simpleDateFormat( conversionContext ) ); @@ -70,7 +70,16 @@ private String getConversionExpression(ConversionContext conversionContext, Stri if ( conversionContext.getDateFormat() != null ) { conversionString.append( " \"" ); conversionString.append( conversionContext.getDateFormat() ); - conversionString.append( "\" " ); + conversionString.append( "\"" ); + + if ( conversionContext.getLocale() != null ) { + conversionString.append( ", " ).append( locale( conversionContext ) ).append( ".forLanguageTag( \"" ); + conversionString.append( conversionContext.getLocale() ); + conversionString.append( "\" ) " ); + } + else { + conversionString.append( " " ); + } } conversionString.append( ")." ); @@ -79,4 +88,5 @@ private String getConversionExpression(ConversionContext conversionContext, Stri return conversionString.toString(); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumStringConversion.java index 50447ad699..d06cad93b4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -39,7 +26,7 @@ public String getToExpression(ConversionContext conversionContext) { @Override public String getFromExpression(ConversionContext conversionContext) { - return "Enum.valueOf( " + conversionContext.getTargetType().getReferenceName() + return "Enum.valueOf( " + conversionContext.getTargetType().createReferenceName() + ".class, )"; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumToIntegerConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumToIntegerConversion.java new file mode 100644 index 0000000000..6904d8ff63 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/EnumToIntegerConversion.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; + +import static org.mapstruct.ap.internal.util.Collections.asSet; + +/** + * Conversion between {@link Enum} and {@link Integer} types. + * + * @author Jose Carlos Campanero Ortiz + */ +public class EnumToIntegerConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".ordinal()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return conversionContext.getTargetType().createReferenceName() + ".values()[ ]"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return asSet( + conversionContext.getTargetType() + ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.java new file mode 100644 index 0000000000..052f2e7224 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.ap.internal.model.common.FieldReference; +import org.mapstruct.ap.internal.model.common.FinalField; +import org.mapstruct.ap.internal.model.common.TypeFactory; + +public class GetDateTimeFormatterField extends FinalField implements FieldReference { + + private final String dateFormat; + + public GetDateTimeFormatterField(TypeFactory typeFactory, String dateFormat) { + super( typeFactory.getType( DateTimeFormatter.class ), getDateTimeFormatterFieldName( dateFormat ) ); + this.dateFormat = dateFormat; + } + + @Override + public Map getTemplateParameter() { + Map parameter = new HashMap<>(); + parameter.put( "dateFormat", dateFormat ); + return parameter; + } + + public static String getDateTimeFormatterFieldName(String dateFormat) { + StringBuilder sb = new StringBuilder(); + sb.append( "dateTimeFormatter_" ); + + dateFormat.codePoints().forEach( cp -> { + if ( Character.isJavaIdentifierPart( cp ) ) { + // safe to character to method name as is + sb.append( Character.toChars( cp ) ); + } + else { + // could not be used in method name + sb.append( "_" ); + } + } ); + + sb.append( "_" ); + + int hashCode = dateFormat.hashCode(); + sb.append( hashCode < 0 ? "0" : "1" ); + sb.append( Math.abs( hashCode ) ); + + return sb.toString(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaInstantToDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaInstantToDateConversion.java new file mode 100644 index 0000000000..3e4fe65eb9 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaInstantToDateConversion.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.Date; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.date; + +/** + * SimpleConversion for mapping {@link java.time.Instant} to + * {@link Date} and vice versa. + */ +public class JavaInstantToDateConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return date( conversionContext ) + ".from( )"; + } + + @Override + protected Set getToConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( conversionContext.getTypeFactory().getType( Date.class ) ); + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".toInstant()"; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToDateConversion.java index ada1efa1ee..489fc39eb4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToDateConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToDateConversion.java @@ -1,23 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; import java.util.Date; import java.util.Set; @@ -29,9 +19,6 @@ import static org.mapstruct.ap.internal.conversion.ConversionUtils.localDateTime; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneId; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.LOCAL_DATE_TIME_FQN; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_ID_FQN; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_OFFSET_FQN; /** * SimpleConversion for mapping {@link java.time.LocalDateTime} to @@ -51,7 +38,7 @@ protected String getToExpression(ConversionContext conversionContext) { protected Set getToConversionImportTypes(ConversionContext conversionContext) { return Collections.asSet( conversionContext.getTypeFactory().getType( Date.class ), - conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) + conversionContext.getTypeFactory().getType( ZoneOffset.class ) ); } @@ -66,8 +53,8 @@ protected String getFromExpression(ConversionContext conversionContext) { @Override protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return Collections.asSet( - conversionContext.getTypeFactory().getType( LOCAL_DATE_TIME_FQN ), - conversionContext.getTypeFactory().getType( ZONE_ID_FQN ) + conversionContext.getTypeFactory().getType( LocalDateTime.class ), + conversionContext.getTypeFactory().getType( ZoneId.class ) ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToLocalDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToLocalDateConversion.java new file mode 100644 index 0000000000..9116bada4c --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToLocalDateConversion.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +import org.mapstruct.ap.internal.model.common.ConversionContext; + +/** + * SimpleConversion for mapping {@link LocalDateTime} to + * {@link LocalDate} and vice versa. + */ + +public class JavaLocalDateTimeToLocalDateConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toLocalDate()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".atStartOfDay()"; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToStringConversion.java index b837e7a0ca..7de296ac6a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateTimeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToDateConversion.java index 03616b86a1..b28bc50785 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToDateConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToDateConversion.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; +import java.time.LocalDateTime; +import java.time.ZoneOffset; import java.util.Date; import java.util.Set; @@ -28,9 +17,6 @@ import static org.mapstruct.ap.internal.conversion.ConversionUtils.date; import static org.mapstruct.ap.internal.conversion.ConversionUtils.localDateTime; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.LOCAL_DATE_TIME_FQN; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_ID_FQN; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_OFFSET_FQN; /** * SimpleConversion for mapping {@link java.time.LocalDate} to @@ -50,7 +36,7 @@ protected String getToExpression(ConversionContext conversionContext) { protected Set getToConversionImportTypes(ConversionContext conversionContext) { return Collections.asSet( conversionContext.getTypeFactory().getType( Date.class ), - conversionContext.getTypeFactory().getType( ZONE_OFFSET_FQN ) + conversionContext.getTypeFactory().getType( ZoneOffset.class ) ); } @@ -65,8 +51,8 @@ protected String getFromExpression(ConversionContext conversionContext) { @Override protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return Collections.asSet( - conversionContext.getTypeFactory().getType( LOCAL_DATE_TIME_FQN ), - conversionContext.getTypeFactory().getType( ZONE_ID_FQN ) + conversionContext.getTypeFactory().getType( LocalDateTime.class ), + conversionContext.getTypeFactory().getType( ZoneOffset.class ) ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToSqlDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToSqlDateConversion.java new file mode 100644 index 0000000000..cfc6ca31d3 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToSqlDateConversion.java @@ -0,0 +1,53 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.sql.Date; +import java.time.ZoneOffset; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.sqlDate; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; + +/** + * SimpleConversion for mapping {@link java.time.LocalDate} to + * {@link Date} and vice versa. + */ +public class JavaLocalDateToSqlDateConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return "new " + sqlDate( conversionContext ) + "( " + + ".atStartOfDay( " + + zoneOffset( conversionContext ) + + ".UTC ).toInstant().toEpochMilli() )"; + } + + @Override + protected Set getToConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( + conversionContext.getTypeFactory().getType( Date.class ), + conversionContext.getTypeFactory().getType( ZoneOffset.class ) + ); + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".toLocalDate()"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( + conversionContext.getTypeFactory().getType( ZoneOffset.class ) + ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToStringConversion.java index be797a90ef..2cc415337b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalDateToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalTimeToStringConversion.java index b59c62f9e1..f7ca411455 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaLocalTimeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaOffsetDateTimeToInstantConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaOffsetDateTimeToInstantConversion.java new file mode 100644 index 0000000000..9c5cb63990 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaOffsetDateTimeToInstantConversion.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.time.ZoneOffset; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; + +public class JavaOffsetDateTimeToInstantConversion extends SimpleConversion { + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toInstant()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".atOffset( " + zoneOffset( conversionContext ) + ".UTC )"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( + conversionContext.getTypeFactory().getType( ZoneOffset.class ) + ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaOffsetDateTimeToLocalDateTimeConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaOffsetDateTimeToLocalDateTimeConversion.java new file mode 100644 index 0000000000..987c4cc625 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaOffsetDateTimeToLocalDateTimeConversion.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.time.ZoneOffset; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; + +public class JavaOffsetDateTimeToLocalDateTimeConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toLocalDateTime()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".atOffset( " + zoneOffset( conversionContext ) + ".UTC )"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( + conversionContext.getTypeFactory().getType( ZoneOffset.class ) + ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToDateConversion.java index dee492b847..cc88d72e4e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToDateConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToDateConversion.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; +import java.time.ZoneId; +import java.time.ZonedDateTime; import java.util.Date; import java.util.Set; @@ -28,8 +17,6 @@ import static org.mapstruct.ap.internal.conversion.ConversionUtils.date; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneId; import static org.mapstruct.ap.internal.conversion.ConversionUtils.zonedDateTime; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONED_DATE_TIME_FQN; -import static org.mapstruct.ap.internal.util.JavaTimeConstants.ZONE_ID_FQN; /** * SimpleConversion for mapping {@link java.time.ZonedDateTime} to @@ -61,8 +48,8 @@ protected String getFromExpression(ConversionContext conversionContext) { @Override protected Set getFromConversionImportTypes(ConversionContext conversionContext) { return Collections.asSet( - conversionContext.getTypeFactory().getType( ZONED_DATE_TIME_FQN ), - conversionContext.getTypeFactory().getType( ZONE_ID_FQN ) + conversionContext.getTypeFactory().getType( ZonedDateTime.class ), + conversionContext.getTypeFactory().getType( ZoneId.class ) ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToInstantConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToInstantConversion.java new file mode 100644 index 0000000000..44cc68c2a7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToInstantConversion.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.time.ZoneOffset; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; + +public class JavaZonedDateTimeToInstantConversion extends SimpleConversion { + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toInstant()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".atZone( " + zoneOffset( conversionContext ) + ".UTC )"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( + conversionContext.getTypeFactory().getType( ZoneOffset.class ) + ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToLocalDateTimeConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToLocalDateTimeConversion.java new file mode 100644 index 0000000000..9a9275cede --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToLocalDateTimeConversion.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.time.ZoneOffset; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.zoneOffset; + +public class JavaZonedDateTimeToLocalDateTimeConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toLocalDateTime()"; + + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return ".atZone( " + zoneOffset( conversionContext ) + ".UTC )"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( + conversionContext.getTypeFactory().getType( ZoneOffset.class ) + ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToStringConversion.java index c7c87bc9be..96fd4115bb 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JavaZonedDateTimeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToCalendarConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToCalendarConversion.java index 230d2e8ce7..d5e74e920a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToCalendarConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToCalendarConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -25,8 +12,8 @@ import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; -import static org.mapstruct.ap.internal.util.Collections.asSet; import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between {@code DateTime} and {@link Calendar}. @@ -47,7 +34,7 @@ protected Set getToConversionImportTypes(ConversionContext conversionConte @Override protected String getFromExpression(ConversionContext conversionContext) { - return "new " + conversionContext.getTargetType().getReferenceName() + "( )"; + return "new " + conversionContext.getTargetType().createReferenceName() + "( )"; } @Override diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToStringConversion.java index e6b1eccba5..6980bf79fc 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaDateTimeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateTimeToStringConversion.java index e731ce425b..4a2804eba0 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateTimeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateToStringConversion.java index b146f0d504..7201a6c65a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalDateToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalTimeToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalTimeToStringConversion.java index 2cea799474..2305f840f1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalTimeToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaLocalTimeToStringConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaTimeToDateConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaTimeToDateConversion.java index 7979099aad..d8212e140e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaTimeToDateConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/JodaTimeToDateConversion.java @@ -1,31 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Date; import java.util.Set; import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Type; +import static org.mapstruct.ap.internal.util.Collections.asSet; + /** * Conversion between the following Joda types and {@link Date}: *
      @@ -45,7 +32,7 @@ protected String getToExpression(ConversionContext conversionContext) { @Override protected String getFromExpression(ConversionContext conversionContext) { - return "new " + conversionContext.getTargetType().getReferenceName() + "( )"; + return "new " + conversionContext.getTargetType().createReferenceName() + "( )"; } @Override diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/LocaleToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/LocaleToStringConversion.java new file mode 100644 index 0000000000..05a6da0b19 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/LocaleToStringConversion.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.Locale; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; + +/** + * Conversion between {@link java.util.Locale} and {@link String}. + * + * @author Jason Bodnar + */ +public class LocaleToStringConversion extends SimpleConversion { + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toLanguageTag()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return locale( conversionContext ) + ".forLanguageTag( )"; + } + + @Override + protected Set getFromConversionImportTypes(final ConversionContext conversionContext) { + return Collections.asSet( conversionContext.getTypeFactory().getType( Locale.class ) ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/OptionalWrapperConversionProvider.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/OptionalWrapperConversionProvider.java new file mode 100644 index 0000000000..db9480662d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/OptionalWrapperConversionProvider.java @@ -0,0 +1,100 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.List; + +import org.mapstruct.ap.internal.model.FromOptionalTypeConversion; +import org.mapstruct.ap.internal.model.HelperMethod; +import org.mapstruct.ap.internal.model.ToOptionalTypeConversion; +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.FieldReference; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; + +/** + * A conversion provider that wraps / unwraps the underlying conversion in Optional. + * e.g., For conversion from {@code Optional} to {@code Integer}. + * + * @author Filip Hrisafov + */ +public class OptionalWrapperConversionProvider implements ConversionProvider { + + private final ConversionProvider conversionProvider; + + public OptionalWrapperConversionProvider(ConversionProvider conversionProvider) { + this.conversionProvider = conversionProvider; + } + + @Override + public Assignment to(ConversionContext conversionContext) { + Assignment assignment = conversionProvider.to( new OptionalConversionContext( conversionContext ) ); + return new ToOptionalTypeConversion( conversionContext.getTargetType(), assignment ); + } + + @Override + public Assignment from(ConversionContext conversionContext) { + Assignment assignment = conversionProvider.to( new OptionalConversionContext( conversionContext ) ); + return new FromOptionalTypeConversion( conversionContext.getSourceType(), assignment ); + } + + @Override + public List getRequiredHelperMethods(ConversionContext conversionContext) { + return conversionProvider.getRequiredHelperMethods( conversionContext ); + } + + @Override + public List getRequiredHelperFields(ConversionContext conversionContext) { + return conversionProvider.getRequiredHelperFields( conversionContext ); + } + + private static class OptionalConversionContext implements ConversionContext { + + private final ConversionContext delegate; + + private OptionalConversionContext(ConversionContext delegate) { + this.delegate = delegate; + } + + @Override + public Type getTargetType() { + return resolveType( delegate.getTargetType() ); + } + + @Override + public Type getSourceType() { + return resolveType( delegate.getSourceType() ); + } + + private Type resolveType(Type type) { + if ( type.isOptionalType() ) { + return type.getOptionalBaseType(); + } + return type; + } + + @Override + public String getDateFormat() { + return delegate.getDateFormat(); + } + + @Override + public String getNumberFormat() { + return delegate.getNumberFormat(); + } + + @Override + public String getLocale() { + return delegate.getLocale(); + } + + @Override + public TypeFactory getTypeFactory() { + return delegate.getTypeFactory(); + } + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToPrimitiveConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToPrimitiveConversion.java index 7f8632488d..34f787b191 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToPrimitiveConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToPrimitiveConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -30,10 +17,6 @@ public class PrimitiveToPrimitiveConversion extends SimpleConversion { private final Class sourceType; public PrimitiveToPrimitiveConversion(Class sourceType) { - if ( !sourceType.isPrimitive() ) { - throw new IllegalArgumentException( sourceType + " is no primitive type." ); - } - this.sourceType = sourceType; } @@ -46,4 +29,5 @@ public String getToExpression(ConversionContext conversionContext) { public String getFromExpression(ConversionContext conversionContext) { return "(" + sourceType + ") "; } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToStringConversion.java index 52cb7ac171..909ce8c0f2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToStringConversion.java @@ -1,25 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.util.Collections; +import java.util.Locale; import java.util.Set; import org.mapstruct.ap.internal.model.common.ConversionContext; @@ -28,6 +17,9 @@ import org.mapstruct.ap.internal.util.Strings; import static org.mapstruct.ap.internal.conversion.ConversionUtils.decimalFormat; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.decimalFormatSymbols; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between primitive types such as {@code byte} or {@code long} and @@ -66,9 +58,15 @@ public String getToExpression(ConversionContext conversionContext) { @Override public Set getToConversionImportTypes(ConversionContext conversionContext) { if ( requiresDecimalFormat( conversionContext ) ) { - return Collections.singleton( - conversionContext.getTypeFactory().getType( DecimalFormat.class ) - ); + if ( conversionContext.getLocale() != null ) { + return asSet( + conversionContext.getTypeFactory().getType( DecimalFormat.class ), + conversionContext.getTypeFactory().getType( DecimalFormatSymbols.class ), + conversionContext.getTypeFactory().getType( Locale.class ) + ); + } + + return Collections.singleton( conversionContext.getTypeFactory().getType( DecimalFormat.class ) ); } return Collections.emptySet(); @@ -93,9 +91,15 @@ public String getFromExpression(ConversionContext conversionContext) { @Override protected Set getFromConversionImportTypes(ConversionContext conversionContext) { if ( requiresDecimalFormat( conversionContext ) ) { - return Collections.singleton( - conversionContext.getTypeFactory().getType( DecimalFormat.class ) - ); + if ( conversionContext.getLocale() != null ) { + return asSet( + conversionContext.getTypeFactory().getType( DecimalFormat.class ), + conversionContext.getTypeFactory().getType( DecimalFormatSymbols.class ), + conversionContext.getTypeFactory().getType( Locale.class ) + ); + } + + return Collections.singleton( conversionContext.getTypeFactory().getType( DecimalFormat.class ) ); } return Collections.emptySet(); @@ -110,6 +114,16 @@ private void appendDecimalFormatter(StringBuilder sb, ConversionContext conversi sb.append( "\"" ); sb.append( conversionContext.getNumberFormat() ); sb.append( "\"" ); + + if ( conversionContext.getLocale() != null ) { + sb.append( ", " ) + .append( decimalFormatSymbols( conversionContext ) ) + .append( ".getInstance( " ) + .append( locale( conversionContext ) ) + .append( ".forLanguageTag( \"" ) + .append( conversionContext.getLocale() ) + .append( " \" ) )" ); + } } sb.append( " )" ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToWrapperConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToWrapperConversion.java index 36a1d4ff74..dc1bde1d05 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToWrapperConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/PrimitiveToWrapperConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -33,13 +20,6 @@ public class PrimitiveToWrapperConversion extends SimpleConversion { private final Class targetType; public PrimitiveToWrapperConversion(Class sourceType, Class targetType) { - if ( !sourceType.isPrimitive() ) { - throw new IllegalArgumentException( sourceType + " is no primitive type." ); - } - if ( targetType.isPrimitive() ) { - throw new IllegalArgumentException( targetType + " is no wrapper type." ); - } - this.sourceType = sourceType; this.targetType = NativeTypes.getPrimitiveType( targetType ); } @@ -58,4 +38,5 @@ public String getToExpression(ConversionContext conversionContext) { public String getFromExpression(ConversionContext conversionContext) { return "." + sourceType.getName() + "Value()"; } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/ReverseConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ReverseConversion.java index 3c914591e8..cb496b0c54 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/ReverseConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/ReverseConversion.java @@ -1,31 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; -import java.util.Collections; import java.util.List; + +import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ConversionContext; -import org.mapstruct.ap.internal.model.HelperMethod; +import org.mapstruct.ap.internal.model.common.FieldReference; /** - * A {@link ConversionProvider} which creates the reversed conversions for a + * * A {@link ConversionProvider} which creates the inversed conversions for a * given conversion provider. * * @author Gunnar Morling @@ -34,7 +22,7 @@ public class ReverseConversion implements ConversionProvider { private ConversionProvider conversionProvider; - public static ReverseConversion reverse(ConversionProvider conversionProvider) { + public static ReverseConversion inverse(ConversionProvider conversionProvider) { return new ReverseConversion( conversionProvider ); } @@ -54,7 +42,11 @@ public Assignment from(ConversionContext conversionContext) { @Override public List getRequiredHelperMethods(ConversionContext conversionContext) { - return Collections.emptyList(); + return conversionProvider.getRequiredHelperMethods( conversionContext ); } + @Override + public List getRequiredHelperFields(ConversionContext conversionContext) { + return conversionProvider.getRequiredHelperFields( conversionContext ); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/SimpleConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/SimpleConversion.java index a69cbfbca7..91051a3e23 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/SimpleConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/SimpleConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -22,10 +9,10 @@ import java.util.List; import java.util.Set; +import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.TypeConversion; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ConversionContext; -import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.common.Type; /** @@ -58,7 +45,6 @@ public List getRequiredHelperMethods(ConversionContext conversionC return Collections.emptyList(); } - /** * Returns the conversion string from source to target. The placeholder {@code } can be used to represent a * reference to the source value. @@ -110,4 +96,5 @@ protected List getToConversionExceptionTypes(ConversionContext conversionC protected List getFromConversionExceptionTypes(ConversionContext conversionContext) { return Collections.emptyList(); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/StaticParseToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/StaticParseToStringConversion.java new file mode 100644 index 0000000000..df3a70ac34 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/StaticParseToStringConversion.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +/** + * Handles conversion between a target type {@code T} and {@link String}, + * where {@code T#parse(String)} and {@code T#toString} are inverse operations. + * The {@link ConversionContext#getTargetType()} is used as the from target type {@code T}. + */ +public class StaticParseToStringConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toString()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return conversionContext.getTargetType().createReferenceName() + ".parse( )"; + } + + @Override + protected Set getFromConversionImportTypes(ConversionContext conversionContext) { + return Collections.asSet( conversionContext.getTargetType() ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/StringBuilderToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/StringBuilderToStringConversion.java new file mode 100644 index 0000000000..2f6705fab8 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/StringBuilderToStringConversion.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import org.mapstruct.ap.internal.model.common.ConversionContext; + +/** + * Handles conversion between a target type {@link StringBuilder} and {@link String}. + * + */ +public class StringBuilderToStringConversion extends SimpleConversion { + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toString()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return "new " + ConversionUtils.stringBuilder( conversionContext ) + "( )"; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/TypeToOptionalConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/TypeToOptionalConversion.java new file mode 100644 index 0000000000..dbab6bc4ca --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/TypeToOptionalConversion.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.Collections; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Strings; + +import static org.mapstruct.ap.internal.conversion.ReverseConversion.inverse; + +/** + * Conversion between {@link java.util.Optional Optional} and its base type. + * + * @author Filip Hrisafov + */ +public class TypeToOptionalConversion extends SimpleConversion { + + static final TypeToOptionalConversion TYPE_TO_OPTIONAL_CONVERSION = new TypeToOptionalConversion(); + static final ConversionProvider OPTIONAL_TO_TYPE_CONVERSION = inverse( TYPE_TO_OPTIONAL_CONVERSION ); + + @Override + protected String getToExpression(ConversionContext conversionContext) { + return conversionContext.getTargetType().asRawType().createReferenceName() + ".of( )"; + } + + @Override + protected Set getToConversionImportTypes(ConversionContext conversionContext) { + return Collections.singleton( conversionContext.getTargetType().asRawType() ); + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + StringBuilder sb = new StringBuilder(".get"); + Type optionalBaseType = conversionContext.getSourceType().getOptionalBaseType(); + if ( optionalBaseType.isPrimitive() ) { + sb.append( "As" ).append( Strings.capitalize( optionalBaseType.getName() ) ); + } + return sb.append( "()" ).toString(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/URIToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/URIToStringConversion.java new file mode 100644 index 0000000000..c25383ae05 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/URIToStringConversion.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.net.URI; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.uri; +import static org.mapstruct.ap.internal.util.Collections.asSet; + +/** + * Conversion between {@link java.net.URI} and {@link String}. + * + * @author Maciej Kucharczyk + */ +public class URIToStringConversion extends SimpleConversion { + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toString()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return uri( conversionContext ) + ".create( )"; + } + + @Override + protected Set getFromConversionImportTypes(final ConversionContext conversionContext) { + return asSet( conversionContext.getTypeFactory().getType( URI.class ) ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/URLToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/URLToStringConversion.java new file mode 100644 index 0000000000..b1fd5f599a --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/URLToStringConversion.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.net.MalformedURLException; +import java.net.URI; +import java.util.List; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.uri; +import static org.mapstruct.ap.internal.util.Collections.asSet; + +/** + * Conversion between {@link java.net.URL} and {@link String}. + * + * @author Adam Szatyin + */ +public class URLToStringConversion extends SimpleConversion { + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toString()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return uri( conversionContext ) + ".create( ).toURL()"; + } + + @Override + protected Set getFromConversionImportTypes(final ConversionContext conversionContext) { + return asSet( conversionContext.getTypeFactory().getType( URI.class ) ); + } + + @Override + protected List getFromConversionExceptionTypes(ConversionContext conversionContext) { + return java.util.Collections.singletonList( + conversionContext.getTypeFactory().getType( MalformedURLException.class ) + ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/UUIDToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/UUIDToStringConversion.java new file mode 100644 index 0000000000..b07d799387 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/UUIDToStringConversion.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.conversion; + +import java.util.Set; +import java.util.UUID; + +import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Collections; + +import static org.mapstruct.ap.internal.conversion.ConversionUtils.uuid; + +/** + * Conversion between {@link java.util.UUID} and {@link String}. + * + * @author Jason Bodnar + */ +public class UUIDToStringConversion extends SimpleConversion { + @Override + protected String getToExpression(ConversionContext conversionContext) { + return ".toString()"; + } + + @Override + protected String getFromExpression(ConversionContext conversionContext) { + return uuid( conversionContext ) + ".fromString( )"; + } + + @Override + protected Set getFromConversionImportTypes(final ConversionContext conversionContext) { + return Collections.asSet( conversionContext.getTypeFactory().getType( UUID.class ) ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToStringConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToStringConversion.java index 32ca05572f..dd7b6bac8d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToStringConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToStringConversion.java @@ -1,25 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.util.Collections; +import java.util.Locale; import java.util.Set; import org.mapstruct.ap.internal.model.common.ConversionContext; @@ -28,6 +17,9 @@ import org.mapstruct.ap.internal.util.Strings; import static org.mapstruct.ap.internal.conversion.ConversionUtils.decimalFormat; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.decimalFormatSymbols; +import static org.mapstruct.ap.internal.conversion.ConversionUtils.locale; +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * Conversion between wrapper types such as {@link Integer} and {@link String}. @@ -65,9 +57,15 @@ public String getToExpression(ConversionContext conversionContext) { @Override public Set getToConversionImportTypes(ConversionContext conversionContext) { if ( requiresDecimalFormat( conversionContext ) ) { - return Collections.singleton( - conversionContext.getTypeFactory().getType( DecimalFormat.class ) - ); + if ( conversionContext.getLocale() != null ) { + return asSet( + conversionContext.getTypeFactory().getType( DecimalFormat.class ), + conversionContext.getTypeFactory().getType( DecimalFormatSymbols.class ), + conversionContext.getTypeFactory().getType( Locale.class ) + ); + } + + return Collections.singleton( conversionContext.getTypeFactory().getType( DecimalFormat.class ) ); } return Collections.emptySet(); @@ -92,9 +90,15 @@ public String getFromExpression(ConversionContext conversionContext) { @Override protected Set getFromConversionImportTypes(ConversionContext conversionContext) { if ( requiresDecimalFormat( conversionContext ) ) { - return Collections.singleton( - conversionContext.getTypeFactory().getType( DecimalFormat.class ) - ); + if ( conversionContext.getLocale() != null ) { + return asSet( + conversionContext.getTypeFactory().getType( DecimalFormat.class ), + conversionContext.getTypeFactory().getType( DecimalFormatSymbols.class ), + conversionContext.getTypeFactory().getType( Locale.class ) + ); + } + + return Collections.singleton( conversionContext.getTypeFactory().getType( DecimalFormat.class ) ); } return Collections.emptySet(); @@ -109,6 +113,16 @@ private void appendDecimalFormatter(StringBuilder sb, ConversionContext conversi sb.append( "\"" ); sb.append( conversionContext.getNumberFormat() ); sb.append( "\"" ); + + if ( conversionContext.getLocale() != null ) { + sb.append( ", " ) + .append( decimalFormatSymbols( conversionContext ) ) + .append( ".getInstance( " ) + .append( locale( conversionContext ) ) + .append( ".forLanguageTag( \"" ) + .append( conversionContext.getLocale() ) + .append( " \" ) )" ); + } } sb.append( " )" ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToWrapperConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToWrapperConversion.java index c4c9d1a8eb..a16ac87274 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToWrapperConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/WrapperToWrapperConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.conversion; @@ -32,13 +19,6 @@ public class WrapperToWrapperConversion extends SimpleConversion { private final Class targetType; public WrapperToWrapperConversion(Class sourceType, Class targetType) { - if ( sourceType.isPrimitive() ) { - throw new IllegalArgumentException( sourceType + " is no wrapper type." ); - } - if ( targetType.isPrimitive() ) { - throw new IllegalArgumentException( targetType + " is no wrapper type." ); - } - this.sourceType = NativeTypes.getPrimitiveType( sourceType ); this.targetType = NativeTypes.getPrimitiveType( targetType ); } @@ -62,4 +42,5 @@ public String getFromExpression(ConversionContext conversionContext) { return "." + sourceType.getName() + "Value()"; } } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/conversion/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/conversion/package-info.java index 407b6355fd..b1002b6a8d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/conversion/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/conversion/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/ClassAccessibilityGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/ClassAccessibilityGem.java new file mode 100644 index 0000000000..609c6d04e7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/ClassAccessibilityGem.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * Gem for the enum {@link org.mapstruct.ClassAccessibility} + * + * @author Raimund Klein + */ +public enum ClassAccessibilityGem { + DEFAULT, PUBLIC, PACKAGE_PRIVATE +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/CollectionMappingStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/CollectionMappingStrategyGem.java new file mode 100644 index 0000000000..f88e21a763 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/CollectionMappingStrategyGem.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * Gem for the enum {@link org.mapstruct.CollectionMappingStrategy} + * + * @author Andreas Gudian + */ +public enum CollectionMappingStrategyGem { + + ACCESSOR_ONLY, + SETTER_PREFERRED, + ADDER_PREFERRED, + TARGET_IMMUTABLE; +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/ConditionStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/ConditionStrategyGem.java new file mode 100644 index 0000000000..adea4b4c1f --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/ConditionStrategyGem.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * @author Filip Hrisafov + */ +public enum ConditionStrategyGem { + + PROPERTIES, + SOURCE_PARAMETERS +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/GemGenerator.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/GemGenerator.java new file mode 100644 index 0000000000..3036faf2eb --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/GemGenerator.java @@ -0,0 +1,94 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.bind.annotation.XmlElementRef; + +import org.mapstruct.AfterMapping; +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWiths; +import org.mapstruct.BeanMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Builder; +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.DecoratedWith; +import org.mapstruct.EnumMapping; +import org.mapstruct.Ignored; +import org.mapstruct.IgnoredList; +import org.mapstruct.InheritConfiguration; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.IterableMapping; +import org.mapstruct.Javadoc; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; +import org.mapstruct.Named; +import org.mapstruct.ObjectFactory; +import org.mapstruct.Qualifier; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.SubclassMapping; +import org.mapstruct.SubclassMappings; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.TargetType; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.control.MappingControl; +import org.mapstruct.control.MappingControls; +import org.mapstruct.tools.gem.GemDefinition; + +/** + * Triggers the generation of gem types using Gem Tools. + * + * @author Gunnar Morling + */ +@GemDefinition(Deprecated.class) +@GemDefinition(AnnotateWith.class) +@GemDefinition(AnnotateWith.Element.class) +@GemDefinition(AnnotateWiths.class) +@GemDefinition(Mapper.class) +@GemDefinition(Mapping.class) +@GemDefinition(Ignored.class) +@GemDefinition(IgnoredList.class) +@GemDefinition(Mappings.class) +@GemDefinition(IterableMapping.class) +@GemDefinition(BeanMapping.class) +@GemDefinition(EnumMapping.class) +@GemDefinition(MapMapping.class) +@GemDefinition(SourcePropertyName.class) +@GemDefinition(SubclassMapping.class) +@GemDefinition(SubclassMappings.class) +@GemDefinition(TargetType.class) +@GemDefinition(TargetPropertyName.class) +@GemDefinition(MappingTarget.class) +@GemDefinition(DecoratedWith.class) +@GemDefinition(MapperConfig.class) +@GemDefinition(InheritConfiguration.class) +@GemDefinition(InheritInverseConfiguration.class) +@GemDefinition(Qualifier.class) +@GemDefinition(Named.class) +@GemDefinition(ObjectFactory.class) +@GemDefinition(AfterMapping.class) +@GemDefinition(BeforeMapping.class) +@GemDefinition(ValueMapping.class) +@GemDefinition(ValueMappings.class) +@GemDefinition(Context.class) +@GemDefinition(Builder.class) +@GemDefinition(Condition.class) +@GemDefinition(Javadoc.class) + +@GemDefinition(MappingControl.class) +@GemDefinition(MappingControls.class) + +// external types +@GemDefinition(XmlElementDecl.class) +@GemDefinition(XmlElementRef.class) +public class GemGenerator { +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/InjectionStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/InjectionStrategyGem.java new file mode 100644 index 0000000000..621d07fd09 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/InjectionStrategyGem.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * Gem for the enum {@link org.mapstruct.InjectionStrategy}. + * + * @author Kevin Grüneberg + */ +public enum InjectionStrategyGem { + + FIELD, + CONSTRUCTOR, + SETTER; +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java new file mode 100644 index 0000000000..bc58024ca3 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingConstantsGem.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * Gem for the enum {@link org.mapstruct.MappingConstants} + * + * @author Sjaak Derksen + */ +public final class MappingConstantsGem { + + private MappingConstantsGem() { + } + + public static final String NULL = ""; + + public static final String ANY_REMAINING = ""; + + public static final String ANY_UNMAPPED = ""; + + public static final String THROW_EXCEPTION = ""; + + public static final String SUFFIX_TRANSFORMATION = "suffix"; + + public static final String STRIP_SUFFIX_TRANSFORMATION = "stripSuffix"; + + public static final String PREFIX_TRANSFORMATION = "prefix"; + + public static final String STRIP_PREFIX_TRANSFORMATION = "stripPrefix"; + + public static final String CASE_TRANSFORMATION = "case"; + + /** + * Gem for the class {@link org.mapstruct.MappingConstants.ComponentModel} + * + */ + public final class ComponentModelGem { + + private ComponentModelGem() { + } + + public static final String DEFAULT = "default"; + + public static final String CDI = "cdi"; + + public static final String SPRING = "spring"; + + public static final String JSR330 = "jsr330"; + + public static final String JAKARTA = "jakarta"; + + public static final String JAKARTA_CDI = "jakarta-cdi"; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingControlUseGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingControlUseGem.java new file mode 100644 index 0000000000..94c8350ef8 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingControlUseGem.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * + * @author Sjaak + */ +public enum MappingControlUseGem { + + BUILT_IN_CONVERSION, + COMPLEX_MAPPING, + DIRECT, + MAPPING_METHOD +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingInheritanceStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingInheritanceStrategyGem.java new file mode 100644 index 0000000000..b07030d8fc --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/MappingInheritanceStrategyGem.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + + +/** + * Gem for the enum {@link org.mapstruct.MappingInheritanceStrategy} + * + * @author Andreas Gudian + */ +public enum MappingInheritanceStrategyGem { + + EXPLICIT( false, false, false ), + AUTO_INHERIT_FROM_CONFIG( true, true, false ), + AUTO_INHERIT_REVERSE_FROM_CONFIG( true, false, true ), + AUTO_INHERIT_ALL_FROM_CONFIG( true, true, true ); + + private final boolean autoInherit; + private final boolean applyForward; + private final boolean applyReverse; + + MappingInheritanceStrategyGem(boolean isAutoInherit, boolean applyForward, boolean applyReverse) { + this.autoInherit = isAutoInherit; + this.applyForward = applyForward; + this.applyReverse = applyReverse; + } + + public boolean isAutoInherit() { + return autoInherit; + } + + public boolean isApplyForward() { + return applyForward; + } + + public boolean isApplyReverse() { + return applyReverse; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValueCheckStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValueCheckStrategyGem.java new file mode 100644 index 0000000000..b7ab803232 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValueCheckStrategyGem.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + + +/** + * Gem for the enum {@link org.mapstruct.NullValueCheckStrategy} + * + * @author Sean Huang + */ +public enum NullValueCheckStrategyGem { + + ON_IMPLICIT_CONVERSION, + ALWAYS; +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValueMappingStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValueMappingStrategyGem.java new file mode 100644 index 0000000000..3d8991f820 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValueMappingStrategyGem.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * Gem for the enum {@link org.mapstruct.NullValueMappingStrategy} + * + * @author Sjaak Derksen + */ +public enum NullValueMappingStrategyGem { + + RETURN_NULL( false ), + RETURN_DEFAULT( true ); + + private final boolean returnDefault; + + NullValueMappingStrategyGem(boolean returnDefault) { + this.returnDefault = returnDefault; + } + + public boolean isReturnDefault() { + return returnDefault; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValuePropertyMappingStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValuePropertyMappingStrategyGem.java new file mode 100644 index 0000000000..93c98b73ac --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/NullValuePropertyMappingStrategyGem.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + + +/** + * Gem for the enum {@link org.mapstruct.NullValuePropertyMappingStrategy} + * + * @author Sjaak Derksen + */ +public enum NullValuePropertyMappingStrategyGem { + + SET_TO_NULL, + SET_TO_DEFAULT, + IGNORE, + CLEAR; +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/ReportingPolicyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/ReportingPolicyGem.java new file mode 100644 index 0000000000..d985c79709 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/ReportingPolicyGem.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +import javax.tools.Diagnostic; +import javax.tools.Diagnostic.Kind; + +/** + * Gem for the enum {@link org.mapstruct.ReportingPolicy}. + * + * @author Gunnar Morling + */ +public enum ReportingPolicyGem { + + IGNORE( null, false, false ), + WARN( Kind.WARNING, true, false ), + ERROR( Kind.ERROR, true, true ); + + private final Diagnostic.Kind diagnosticKind; + private final boolean requiresReport; + private final boolean failsBuild; + + ReportingPolicyGem(Diagnostic.Kind diagnosticKind, boolean requiresReport, boolean failsBuild) { + this.requiresReport = requiresReport; + this.diagnosticKind = diagnosticKind; + this.failsBuild = failsBuild; + } + + public Diagnostic.Kind getDiagnosticKind() { + return diagnosticKind; + } + + public boolean requiresReport() { + return requiresReport; + } + + public boolean failsBuild() { + return failsBuild; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/SubclassExhaustiveStrategyGem.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/SubclassExhaustiveStrategyGem.java new file mode 100644 index 0000000000..2367d649a9 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/SubclassExhaustiveStrategyGem.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem; + +/** + * Gem for the enum {@link org.mapstruct.SubclassExhaustiveStrategy} + * + * @author Ben Zegveld + */ +public enum SubclassExhaustiveStrategyGem { + + COMPILE_ERROR( false ), + RUNTIME_EXCEPTION( true ); + + private final boolean abstractReturnTypeAllowed; + + SubclassExhaustiveStrategyGem(boolean abstractReturnTypeAllowed) { + this.abstractReturnTypeAllowed = abstractReturnTypeAllowed; + } + + public boolean isAbstractReturnTypeAllowed() { + return abstractReturnTypeAllowed; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/jakarta/JakartaGemGenerator.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/jakarta/JakartaGemGenerator.java new file mode 100644 index 0000000000..93bdebeaef --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/jakarta/JakartaGemGenerator.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.gem.jakarta; + +import jakarta.xml.bind.annotation.XmlElementDecl; +import jakarta.xml.bind.annotation.XmlElementRef; +import org.mapstruct.tools.gem.GemDefinition; + +/** + * This class is a temporary solution to an issue in the Gem Tools library. + * + *

      + * This class can be merged with {@link org.mapstruct.ap.internal.gem.GemGenerator} + * after the mentioned issue is resolved. + *

      + * + * @see Gem Tools issue #10 + * @author Iaroslav Bogdanchikov + */ +@GemDefinition(XmlElementDecl.class) +@GemDefinition(XmlElementRef.class) +class JakartaGemGenerator { +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/gem/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/gem/package-info.java new file mode 100644 index 0000000000..b5f4330e4e --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/gem/package-info.java @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + *

      + * This package contains the generated gem types for accessing the MapStruct annotations in a comfortable way. + *

      + */ +package org.mapstruct.ap.internal.gem; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java index 9a2ec6b4ad..8859e542b8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractBaseBuilder.java @@ -1,31 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; +import java.util.function.Supplier; +import javax.lang.model.element.AnnotationMirror; + import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.MappingMethodUtils; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.util.MapperConfiguration; import org.mapstruct.ap.internal.util.Message; /** @@ -52,7 +40,7 @@ public B method(Method sourceMethod) { } /** - * Checks if MapStruct is allowed to generate an automatic sub-mapping between {@code sourceType} and @{code + * Checks if MapStruct is allowed to generate an automatic sub-mapping between {@code sourceType} and {@code * targetType}. * This will evaluate to {@code true}, when: *
    • @@ -72,13 +60,12 @@ boolean canGenerateAutoSubMappingBetween(Type sourceType, Type targetType) { } private boolean isDisableSubMappingMethodsGeneration() { - MapperConfiguration configuration = MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ); - return configuration.isDisableSubMappingMethodsGeneration(); + return method.getOptions().getMapper().isDisableSubMappingMethodsGeneration(); } /** * Creates a forged assignment from the provided {@code sourceRHS} and {@code forgedMethod}. If a mapping method - * for the {@code forgedMethod} already exists, then this method used for the assignment. + * for the {@code forgedMethod} already exists, this method will be used for the assignment. * * @param sourceRHS that needs to be used for the assignment * @param forgedMethod the forged method for which we want to create an {@link Assignment} @@ -87,30 +74,40 @@ private boolean isDisableSubMappingMethodsGeneration() { */ Assignment createForgedAssignment(SourceRHS sourceRHS, ForgedMethod forgedMethod) { - if ( ctx.getForgedMethodsUnderCreation().containsKey( forgedMethod ) ) { - return createAssignment( sourceRHS, ctx.getForgedMethodsUnderCreation().get( forgedMethod ) ); - } - else { - ctx.getForgedMethodsUnderCreation().put( forgedMethod, forgedMethod ); - } - - MappingMethod forgedMappingMethod; + Supplier forgedMappingMethodCreator; if ( MappingMethodUtils.isEnumMapping( forgedMethod ) ) { - forgedMappingMethod = new ValueMappingMethod.Builder() + forgedMappingMethodCreator = () -> new ValueMappingMethod.Builder() .method( forgedMethod ) - .valueMappings( forgedMethod.getMappingOptions().getValueMappings() ) + .valueMappings( forgedMethod.getOptions().getValueMappings() ) + .enumMapping( forgedMethod.getOptions().getEnumMappingOptions() ) .mappingContext( ctx ) .build(); } else { - forgedMappingMethod = new BeanMappingMethod.Builder() + forgedMappingMethodCreator = () -> new BeanMappingMethod.Builder() .forgedMethod( forgedMethod ) .mappingContext( ctx ) .build(); } + return getOrCreateForgedAssignment( sourceRHS, forgedMethod, forgedMappingMethodCreator ); + } + + Assignment getOrCreateForgedAssignment(SourceRHS sourceRHS, ForgedMethod forgedMethod, + Supplier mappingMethodCreator) { + + if ( ctx.getForgedMethodsUnderCreation().containsKey( forgedMethod ) ) { + return createAssignment( sourceRHS, ctx.getForgedMethodsUnderCreation().get( forgedMethod ) ); + } + else { + ctx.getForgedMethodsUnderCreation().put( forgedMethod, forgedMethod ); + } + + MappingMethod forgedMappingMethod = mappingMethodCreator.get(); + Assignment forgedAssignment = createForgedAssignment( sourceRHS, forgedMethod, forgedMappingMethod ); ctx.getForgedMethodsUnderCreation().remove( forgedMethod ); + return forgedAssignment; } @@ -118,8 +115,8 @@ Assignment createForgedAssignment(SourceRHS source, ForgedMethod methodRef, Mapp if ( mappingMethod == null ) { return null; } - if (methodRef.getMappingOptions().isRestrictToDefinedMappings() || - !ctx.getMappingsToGenerate().contains( mappingMethod )) { + if ( methodRef.getMappingReferences().isRestrictToDefinedMappings() || + !ctx.getMappingsToGenerate().contains( mappingMethod ) ) { // If the mapping options are restricted only to the defined mappings, then use the mapping method. // See https://github.com/mapstruct/mapstruct/issues/1148 ctx.getMappingsToGenerate().add( mappingMethod ); @@ -152,15 +149,40 @@ private Assignment createAssignment(SourceRHS source, ForgedMethod methodRef) { * @param targetPropertyName the name of the target property */ void reportCannotCreateMapping(Method method, String sourceErrorMessagePart, Type sourceType, Type targetType, + String targetPropertyName) { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.PROPERTYMAPPING_MAPPING_NOT_FOUND, + sourceErrorMessagePart, + targetType.describe(), + targetPropertyName, + targetType.describe(), + sourceType.describe() + ); + } + + /** + * Reports that a mapping could not be created. + * + * @param method the method that should be mapped + * @param posHint hint which @Mapping is the culprit + * @param sourceErrorMessagePart the error message part for the source + * @param sourceType the source type of the mapping + * @param targetType the type of the target mapping + * @param targetPropertyName the name of the target property + */ + void reportCannotCreateMapping(Method method, AnnotationMirror posHint, String sourceErrorMessagePart, + Type sourceType, Type targetType, String targetPropertyName) { ctx.getMessager().printMessage( method.getExecutable(), + posHint, Message.PROPERTYMAPPING_MAPPING_NOT_FOUND, sourceErrorMessagePart, - targetType, + targetType.describe(), targetPropertyName, - targetType, - sourceType + targetType.describe(), + sourceType.describe() ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java index 597ad093b8..c124306105 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AbstractMappingMethodBuilder.java @@ -1,81 +1,100 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ - package org.mapstruct.ap.internal.model; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.mapstruct.ap.internal.model.beanmapping.MappingReferences; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; +import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.util.Strings; /** * An abstract builder that can be reused for building {@link MappingMethod}(s). * + * @param the builder itself that needs to be used for chaining + * @param the method that the builder builds * @author Filip Hrisafov */ public abstract class AbstractMappingMethodBuilder, - M extends MappingMethod> extends AbstractBaseBuilder { + M extends MappingMethod> + extends AbstractBaseBuilder { public AbstractMappingMethodBuilder(Class selfType) { super( selfType ); } + private interface ForgeMethodCreator { + ForgedMethod createMethod(String name, Type sourceType, Type returnType, Method basedOn, + ForgedMethodHistory history, boolean forgedNameBased); + + static ForgeMethodCreator forSubclassMapping(MappingReferences mappingReferences) { + return (name, sourceType, targetType, method, description, + forgedNameBased) -> ForgedMethod + .forSubclassMapping( + name, + sourceType, + targetType, + method, + mappingReferences, + description, + forgedNameBased ); + } + } + public abstract M build(); + private ForgedMethodHistory description; + /** * @return {@code true} if property names should be used for the creation of the {@link ForgedMethodHistory}. */ protected abstract boolean shouldUsePropertyNamesInHistory(); Assignment forgeMapping(SourceRHS sourceRHS, Type sourceType, Type targetType) { + return forgeMapping( sourceRHS, sourceType, targetType, ForgedMethod::forElementMapping ); + } + + Assignment forgeSubclassMapping(SourceRHS sourceRHS, Type sourceType, Type targetType, + MappingReferences mappingReferences) { + return forgeMapping( + sourceRHS, + sourceType, + targetType, + ForgeMethodCreator.forSubclassMapping( mappingReferences ) ); + } + + private Assignment forgeMapping(SourceRHS sourceRHS, Type sourceType, Type targetType, + ForgeMethodCreator forgeMethodCreator) { if ( !canGenerateAutoSubMappingBetween( sourceType, targetType ) ) { return null; } String name = getName( sourceType, targetType ); - name = Strings.getSaveVariableName( name, ctx.getNamesOfMappingsToGenerate() ); + name = Strings.getSafeVariableName( name, ctx.getReservedNames() ); ForgedMethodHistory history = null; if ( method instanceof ForgedMethod ) { history = ( (ForgedMethod) method ).getHistory(); } - ForgedMethod forgedMethod = new ForgedMethod( - name, - sourceType, + + description = new ForgedMethodHistory( + history, + Strings.stubPropertyName( sourceRHS.getSourceType().getName() ), + Strings.stubPropertyName( targetType.getName() ), + sourceRHS.getSourceType(), targetType, - method.getMapperConfiguration(), - method.getExecutable(), - method.getContextParameters(), - method.getContextProvidedMethods(), - new ForgedMethodHistory( - history, - Strings.stubPropertyName( sourceRHS.getSourceType().getName() ), - Strings.stubPropertyName( targetType.getName() ), - sourceRHS.getSourceType(), - targetType, - shouldUsePropertyNamesInHistory(), - sourceRHS.getSourceErrorMessagePart() - ), - null, - true - ); + shouldUsePropertyNamesInHistory(), + sourceRHS.getSourceErrorMessagePart() ); + + ForgedMethod forgedMethod = + forgeMethodCreator.createMethod( name, sourceType, targetType, method, description, true ); return createForgedAssignment( sourceRHS, forgedMethod ); } @@ -94,4 +113,28 @@ private String getName(Type type) { builder.append( type.getIdentification() ); return builder.toString(); } + + public ForgedMethodHistory getDescription() { + return description; + } + + public List getMethodAnnotations() { + if ( method instanceof ForgedMethod ) { + return Collections.emptyList(); + } + AdditionalAnnotationsBuilder additionalAnnotationsBuilder = + new AdditionalAnnotationsBuilder( + ctx.getElementUtils(), + ctx.getTypeFactory(), + ctx.getMessager() ); + List annotations = new ArrayList<>( + additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) + ); + + if ( method.overridesMethod() ) { + annotations.add( new Annotation( ctx.getTypeFactory().getType( Override.class ) ) ); + } + return annotations; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AdditionalAnnotationsBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AdditionalAnnotationsBuilder.java new file mode 100644 index 0000000000..cb9289e057 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AdditionalAnnotationsBuilder.java @@ -0,0 +1,644 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Target; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.AnnotateWithGem; +import org.mapstruct.ap.internal.gem.AnnotateWithsGem; +import org.mapstruct.ap.internal.gem.DeprecatedGem; +import org.mapstruct.ap.internal.gem.ElementGem; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement.AnnotationElementType; +import org.mapstruct.ap.internal.model.annotation.EnumAnnotationElementHolder; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.RepeatableAnnotations; +import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.spi.TypeHierarchyErroneousException; +import org.mapstruct.tools.gem.GemValue; + +import static javax.lang.model.util.ElementFilter.methodsIn; + +/** + * Helper class which is responsible for collecting all additional annotations that should be added. + * + * @author Ben Zegveld + * @since 1.5 + */ +public class AdditionalAnnotationsBuilder + extends RepeatableAnnotations { + private static final String ANNOTATE_WITH_FQN = "org.mapstruct.AnnotateWith"; + private static final String ANNOTATE_WITHS_FQN = "org.mapstruct.AnnotateWiths"; + private TypeFactory typeFactory; + private FormattingMessager messager; + + public AdditionalAnnotationsBuilder(ElementUtils elementUtils, TypeFactory typeFactory, + FormattingMessager messager) { + super( elementUtils, ANNOTATE_WITH_FQN, ANNOTATE_WITHS_FQN ); + this.typeFactory = typeFactory; + this.messager = messager; + } + + @Override + protected AnnotateWithGem singularInstanceOn(Element element) { + return AnnotateWithGem.instanceOn( element ); + } + + @Override + protected AnnotateWithsGem multipleInstanceOn(Element element) { + return AnnotateWithsGem.instanceOn( element ); + } + + @Override + protected void addInstance(AnnotateWithGem gem, Element source, Set mappings) { + buildAnnotation( gem, source ).ifPresent( t -> addAndValidateMapping( mappings, source, gem, t ) ); + } + + @Override + protected void addInstances(AnnotateWithsGem gem, Element source, Set mappings) { + for ( AnnotateWithGem annotateWithGem : gem.value().get() ) { + buildAnnotation( + annotateWithGem, + source ).ifPresent( t -> addAndValidateMapping( mappings, source, annotateWithGem, t ) ); + } + } + + @Override + public Set getProcessedAnnotations(Element source) { + Set processedAnnotations = super.getProcessedAnnotations( source ); + return addDeprecatedAnnotation( source, processedAnnotations ); + } + + private Set addDeprecatedAnnotation(Element source, Set annotations) { + DeprecatedGem deprecatedGem = DeprecatedGem.instanceOn( source ); + if ( deprecatedGem == null ) { + return annotations; + } + Type deprecatedType = typeFactory.getType( Deprecated.class ); + if ( annotations.stream().anyMatch( annotation -> annotation.getType().equals( deprecatedType ) ) ) { + messager.printMessage( + source, + deprecatedGem.mirror(), + Message.ANNOTATE_WITH_DUPLICATE, + deprecatedType.describe() ); + return annotations; + } + List annotationElements = new ArrayList<>(); + if ( deprecatedGem.since() != null && deprecatedGem.since().hasValue() ) { + annotationElements.add( new AnnotationElement( + AnnotationElementType.STRING, + "since", + Collections.singletonList( deprecatedGem.since().getValue() ) + ) ); + } + if ( deprecatedGem.forRemoval() != null && deprecatedGem.forRemoval().hasValue() ) { + annotationElements.add( new AnnotationElement( + AnnotationElementType.BOOLEAN, + "forRemoval", + Collections.singletonList( deprecatedGem.forRemoval().getValue() ) + ) ); + } + annotations.add( new Annotation(deprecatedType, annotationElements ) ); + return annotations; + } + + private void addAndValidateMapping(Set mappings, Element source, AnnotateWithGem gem, Annotation anno) { + if ( anno.getType().getTypeElement().getAnnotation( Repeatable.class ) == null ) { + if ( mappings.stream().anyMatch( existing -> existing.getType().equals( anno.getType() ) ) ) { + messager.printMessage( + source, + gem.mirror(), + Message.ANNOTATE_WITH_ANNOTATION_IS_NOT_REPEATABLE, + anno.getType().describe() ); + return; + } + } + if ( mappings.stream().anyMatch( existing -> { + return existing.getType().equals( anno.getType() ) + && existing.getProperties().equals( anno.getProperties() ); + } ) ) { + messager.printMessage( + source, + gem.mirror(), + Message.ANNOTATE_WITH_DUPLICATE, + anno.getType().describe() ); + return; + } + mappings.add( anno ); + } + + private Optional buildAnnotation(AnnotateWithGem annotationGem, Element element) { + Type annotationType = typeFactory.getType( getTypeMirror( annotationGem.value() ) ); + List eleGems = annotationGem.elements().get(); + if ( isValid( annotationType, eleGems, element, annotationGem.mirror() ) ) { + return Optional.of( new Annotation( annotationType, convertToProperties( eleGems ) ) ); + } + return Optional.empty(); + } + + private List convertToProperties(List eleGems) { + return eleGems.stream().map( gem -> convertToProperty( gem, typeFactory ) ).collect( Collectors.toList() ); + } + + private enum ConvertToProperty { + BOOLEAN( + AnnotationElementType.BOOLEAN, + (eleGem, typeFactory) -> eleGem.booleans().get(), + eleGem -> eleGem.booleans().hasValue() + ), + BYTE( + AnnotationElementType.BYTE, + (eleGem, typeFactory) -> eleGem.bytes().get(), + eleGem -> eleGem.bytes().hasValue() + ), + CHARACTER( + AnnotationElementType.CHARACTER, + (eleGem, typeFactory) -> eleGem.chars().get(), + eleGem -> eleGem.chars().hasValue() + ), + CLASSES( + AnnotationElementType.CLASS, + (eleGem, typeFactory) -> { + return eleGem.classes().get().stream().map( typeFactory::getType ).collect( Collectors.toList() ); + }, + eleGem -> eleGem.classes().hasValue() + ), + DOUBLE( + AnnotationElementType.DOUBLE, + (eleGem, typeFactory) -> eleGem.doubles().get(), + eleGem -> eleGem.doubles().hasValue() + ), + ENUM( + AnnotationElementType.ENUM, + (eleGem, typeFactory) -> { + List values = new ArrayList<>(); + for ( String enumName : eleGem.enums().get() ) { + Type type = typeFactory.getType( eleGem.enumClass().get() ); + values.add( new EnumAnnotationElementHolder( type, enumName ) ); + } + return values; + }, + eleGem -> eleGem.enums().hasValue() && eleGem.enumClass().hasValue() + ), + FLOAT( + AnnotationElementType.FLOAT, + (eleGem, typeFactory) -> eleGem.floats().get(), + eleGem -> eleGem.floats().hasValue() + ), + INT( + AnnotationElementType.INTEGER, + (eleGem, typeFactory) -> eleGem.ints().get(), + eleGem -> eleGem.ints().hasValue() + ), + LONG( + AnnotationElementType.LONG, + (eleGem, typeFactory) -> eleGem.longs().get(), + eleGem -> eleGem.longs().hasValue() + ), + SHORT( + AnnotationElementType.SHORT, + (eleGem, typeFactory) -> eleGem.shorts().get(), + eleGem -> eleGem.shorts().hasValue() + ), + STRING( + AnnotationElementType.STRING, + (eleGem, typeFactory) -> eleGem.strings().get(), + eleGem -> eleGem.strings().hasValue() + ); + + private final AnnotationElementType type; + private final BiFunction> factory; + private final Predicate usabilityChecker; + + ConvertToProperty(AnnotationElementType type, + BiFunction> factory, + Predicate usabilityChecker) { + this.type = type; + this.factory = factory; + this.usabilityChecker = usabilityChecker; + } + + AnnotationElement toProperty(ElementGem eleGem, TypeFactory typeFactory) { + return new AnnotationElement( + type, + eleGem.name().get(), + factory.apply( eleGem, typeFactory ) + ); + } + + boolean isUsable(ElementGem eleGem) { + return usabilityChecker.test( eleGem ); + } + } + + private AnnotationElement convertToProperty(ElementGem eleGem, TypeFactory typeFactory) { + for ( ConvertToProperty convertToJava : ConvertToProperty.values() ) { + if ( convertToJava.isUsable( eleGem ) ) { + return convertToJava.toProperty( eleGem, typeFactory ); + } + } + return null; + } + + private boolean isValid(Type annotationType, List eleGems, Element element, + AnnotationMirror annotationMirror) { + boolean isValid = true; + if ( !annotationIsAllowed( annotationType, element, annotationMirror ) ) { + isValid = false; + } + + List annotationElements = methodsIn( annotationType.getTypeElement() + .getEnclosedElements() ); + if ( !allRequiredElementsArePresent( annotationType, annotationElements, eleGems, element, + annotationMirror ) ) { + isValid = false; + } + if ( !allElementsAreKnownInAnnotation( annotationType, annotationElements, eleGems, element ) ) { + isValid = false; + } + if ( !allElementsAreOfCorrectType( annotationType, annotationElements, eleGems, element ) ) { + isValid = false; + } + if ( !enumConstructionIsCorrectlyUsed( eleGems, element ) ) { + isValid = false; + } + if ( !allElementsAreUnique( eleGems, element ) ) { + isValid = false; + } + return isValid; + } + + private boolean allElementsAreUnique(List eleGems, Element element) { + boolean isValid = true; + List checkedElements = new ArrayList<>(); + for ( ElementGem elementGem : eleGems ) { + String elementName = elementGem.name().get(); + if ( checkedElements.contains( elementName ) ) { + isValid = false; + messager + .printMessage( + element, + elementGem.mirror(), + Message.ANNOTATE_WITH_DUPLICATE_PARAMETER, + elementName ); + } + else { + checkedElements.add( elementName ); + } + } + return isValid; + } + + private boolean enumConstructionIsCorrectlyUsed(List eleGems, Element element) { + boolean isValid = true; + for ( ElementGem elementGem : eleGems ) { + if ( elementGem.enums().hasValue() ) { + if ( elementGem.enumClass().getValue() == null ) { + isValid = false; + messager + .printMessage( + element, + elementGem.mirror(), + Message.ANNOTATE_WITH_ENUM_CLASS_NOT_DEFINED ); + } + else { + Type type = typeFactory.getType( getTypeMirror( elementGem.enumClass() ) ); + if ( type.isEnumType() ) { + List enumConstants = type.getEnumConstants(); + for ( String enumName : elementGem.enums().get() ) { + if ( !enumConstants.contains( enumName ) ) { + isValid = false; + messager + .printMessage( + element, + elementGem.mirror(), + elementGem.enums().getAnnotationValue(), + Message.ANNOTATE_WITH_ENUM_VALUE_DOES_NOT_EXIST, + type.describe(), + enumName ); + } + } + } + } + } + else if ( elementGem.enumClass().getValue() != null ) { + isValid = false; + messager.printMessage( element, elementGem.mirror(), Message.ANNOTATE_WITH_ENUMS_NOT_DEFINED ); + } + } + return isValid; + } + + private boolean annotationIsAllowed(Type annotationType, Element element, AnnotationMirror annotationMirror) { + Target target = annotationType.getTypeElement().getAnnotation( Target.class ); + if ( target == null ) { + return true; + } + + Set annotationTargets = Stream.of( target.value() ) + // The eclipse compiler returns null for some values + // Therefore, we filter out null values + .filter( Objects::nonNull ) + .collect( Collectors.toCollection( () -> EnumSet.noneOf( ElementType.class ) ) ); + + boolean isValid = true; + if ( isTypeTarget( element ) && !annotationTargets.contains( ElementType.TYPE ) ) { + isValid = false; + messager.printMessage( + element, + annotationMirror, + Message.ANNOTATE_WITH_NOT_ALLOWED_ON_CLASS, + annotationType.describe() + ); + } + if ( isMethodTarget( element ) && !annotationTargets.contains( ElementType.METHOD ) ) { + isValid = false; + messager.printMessage( + element, + annotationMirror, + Message.ANNOTATE_WITH_NOT_ALLOWED_ON_METHODS, + annotationType.describe() + ); + } + return isValid; + } + + private boolean isTypeTarget(Element element) { + return element.getKind().isInterface() || element.getKind().isClass(); + } + + private boolean isMethodTarget(Element element) { + return element.getKind() == ElementKind.METHOD; + } + + private boolean allElementsAreKnownInAnnotation(Type annotationType, List annotationParameters, + List eleGems, Element element) { + Set allowedAnnotationParameters = annotationParameters.stream() + .map( ee -> ee.getSimpleName().toString() ) + .collect( Collectors.toSet() ); + boolean isValid = true; + for ( ElementGem eleGem : eleGems ) { + if ( eleGem.name().isValid() + && !allowedAnnotationParameters.contains( eleGem.name().get() ) ) { + isValid = false; + messager + .printMessage( + element, + eleGem.mirror(), + eleGem.name().getAnnotationValue(), + Message.ANNOTATE_WITH_UNKNOWN_PARAMETER, + eleGem.name().get(), + annotationType.describe(), + Strings.getMostSimilarWord( eleGem.name().get(), allowedAnnotationParameters ) + ); + } + } + return isValid; + } + + private boolean allRequiredElementsArePresent(Type annotationType, List annotationParameters, + List elements, Element element, + AnnotationMirror annotationMirror) { + + boolean valid = true; + for ( ExecutableElement annotationParameter : annotationParameters ) { + if ( annotationParameter.getDefaultValue() == null ) { + // Mandatory parameter, must be present in the elements + String parameterName = annotationParameter.getSimpleName().toString(); + boolean elementGemDefined = false; + for ( ElementGem elementGem : elements ) { + if ( elementGem.isValid() && elementGem.name().get().equals( parameterName ) ) { + elementGemDefined = true; + break; + } + } + + if ( !elementGemDefined ) { + valid = false; + messager + .printMessage( + element, + annotationMirror, + Message.ANNOTATE_WITH_MISSING_REQUIRED_PARAMETER, + parameterName, + annotationType.describe() + ); + } + } + } + + + return valid; + } + + private boolean allElementsAreOfCorrectType(Type annotationType, List annotationParameters, + List elements, + Element element) { + Map annotationParametersByName = + annotationParameters.stream() + .collect( Collectors.toMap( ee -> ee.getSimpleName().toString(), Function.identity() ) ); + boolean isValid = true; + for ( ElementGem eleGem : elements ) { + Type annotationParameterType = getAnnotationParameterType( annotationParametersByName, eleGem ); + Type annotationParameterTypeSingular = getNonArrayType( annotationParameterType ); + if ( annotationParameterTypeSingular == null ) { + continue; + } + if ( hasTooManyDifferentTypes( eleGem ) ) { + isValid = false; + messager.printMessage( + element, + eleGem.mirror(), + eleGem.name().getAnnotationValue(), + Message.ANNOTATE_WITH_TOO_MANY_VALUE_TYPES, + eleGem.name().get(), + annotationParameterType.describe(), + annotationType.describe() + ); + } + else { + Map elementTypes = getParameterTypes( eleGem ); + Set reportedSizeError = new HashSet<>(); + for ( Type eleGemType : elementTypes.keySet() ) { + if ( !sameTypeOrAssignableClass( annotationParameterTypeSingular, eleGemType ) ) { + isValid = false; + messager.printMessage( + element, + eleGem.mirror(), + eleGem.name().getAnnotationValue(), + Message.ANNOTATE_WITH_WRONG_PARAMETER, + eleGem.name().get(), + eleGemType.describe(), + annotationParameterType.describe(), + annotationType.describe() + ); + } + else if ( !annotationParameterType.isArrayType() + && elementTypes.get( eleGemType ) > 1 + && !reportedSizeError.contains( eleGem ) ) { + isValid = false; + messager.printMessage( + element, + eleGem.mirror(), + Message.ANNOTATE_WITH_PARAMETER_ARRAY_NOT_EXPECTED, + eleGem.name().get(), + annotationType.describe() + ); + reportedSizeError.add( eleGem ); + } + } + } + } + return isValid; + } + + private boolean hasTooManyDifferentTypes( ElementGem eleGem ) { + return Arrays.stream( ConvertToProperty.values() ) + .filter( anotationElement -> anotationElement.isUsable( eleGem ) ) + .count() > 1; + } + + private Type getNonArrayType(Type annotationParameterType) { + if ( annotationParameterType == null ) { + return null; + } + if ( annotationParameterType.isArrayType() ) { + return annotationParameterType.getComponentType(); + } + + return annotationParameterType; + } + + private boolean sameTypeOrAssignableClass(Type annotationParameterType, Type eleGemType) { + return annotationParameterType.equals( eleGemType ) + || eleGemType.isAssignableTo( getTypeBound( annotationParameterType ) ); + } + + private Type getTypeBound(Type annotationParameterType) { + List typeParameters = annotationParameterType.getTypeParameters(); + if ( typeParameters.size() != 1 ) { + return annotationParameterType; + } + return typeParameters.get( 0 ).getTypeBound(); + } + + private Map getParameterTypes(ElementGem eleGem) { + Map suppliedParameterTypes = new HashMap<>(); + if ( eleGem.booleans().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( boolean.class ), + eleGem.booleans().get().size() ); + } + if ( eleGem.bytes().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( byte.class ), + eleGem.bytes().get().size() ); + } + if ( eleGem.chars().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( char.class ), + eleGem.chars().get().size() ); + } + if ( eleGem.classes().hasValue() ) { + for ( TypeMirror mirror : eleGem.classes().get() ) { + suppliedParameterTypes.put( + typeFactory.getType( typeMirrorFromAnnotation( mirror ) ), + eleGem.classes().get().size() + ); + } + } + if ( eleGem.doubles().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( double.class ), + eleGem.doubles().get().size() ); + } + if ( eleGem.floats().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( float.class ), + eleGem.floats().get().size() ); + } + if ( eleGem.ints().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( int.class ), + eleGem.ints().get().size() ); + } + if ( eleGem.longs().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( long.class ), + eleGem.longs().get().size() ); + } + if ( eleGem.shorts().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( short.class ), + eleGem.shorts().get().size() ); + } + if ( eleGem.strings().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( String.class ), + eleGem.strings().get().size() ); + } + if ( eleGem.enums().hasValue() && eleGem.enumClass().hasValue() ) { + suppliedParameterTypes.put( + typeFactory.getType( getTypeMirror( eleGem.enumClass() ) ), + eleGem.enums().get().size() ); + } + return suppliedParameterTypes; + } + + private Type getAnnotationParameterType(Map annotationParameters, + ElementGem element) { + if ( annotationParameters.containsKey( element.name().get() ) ) { + return typeFactory.getType( annotationParameters.get( element.name().get() ).getReturnType() ); + } + else { + return null; + } + } + + private TypeMirror getTypeMirror(GemValue gemValue) { + return typeMirrorFromAnnotation( gemValue.getValue() ); + } + + private TypeMirror typeMirrorFromAnnotation(TypeMirror typeMirror) { + if ( typeMirror == null ) { + // When a class used in an annotation is created by another annotation processor + // then javac will not return correct TypeMirror with TypeKind#ERROR, but rather a string "" + // the gem tools would return a null TypeMirror in that case. + // Therefore, throw TypeHierarchyErroneousException so we can postpone the generation of the mapper + throw new TypeHierarchyErroneousException( typeMirror ); + } + + return typeMirror; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedConstructor.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedConstructor.java index 7a12cf61db..889d602cdb 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedConstructor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedConstructor.java @@ -1,23 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -32,22 +20,57 @@ */ public class AnnotatedConstructor extends ModelElement implements Constructor { - private final String name; + private String name; private final List mapperReferences; private final List annotations; - private final boolean publicEmptyConstructor; + private final NoArgumentConstructor noArgumentConstructor; + private final Set fragments; - public AnnotatedConstructor(String name, List mapperReferences, - List annotations, boolean publicEmptyConstructor) { + public static AnnotatedConstructor forComponentModels(String name, + List mapperReferences, + List annotations, + Constructor constructor, + boolean includeNoArgConstructor) { + + NoArgumentConstructor noArgumentConstructor = null; + if ( constructor instanceof NoArgumentConstructor ) { + noArgumentConstructor = (NoArgumentConstructor) constructor; + } + NoArgumentConstructor noArgConstructorToBeIncluded = null; + Set fragmentsToBeIncluded = Collections.emptySet(); + if ( includeNoArgConstructor ) { + if ( noArgumentConstructor != null ) { + noArgConstructorToBeIncluded = noArgumentConstructor; + } + else { + noArgConstructorToBeIncluded = new NoArgumentConstructor( name, fragmentsToBeIncluded ); + } + } + else if ( noArgumentConstructor != null ) { + fragmentsToBeIncluded = noArgumentConstructor.getFragments(); + } + return new AnnotatedConstructor( + name, + mapperReferences, + annotations, + noArgConstructorToBeIncluded, + fragmentsToBeIncluded + ); + } + + private AnnotatedConstructor(String name, List mapperReferences, + List annotations, NoArgumentConstructor noArgumentConstructor, + Set fragments) { this.name = name; this.mapperReferences = mapperReferences; this.annotations = annotations; - this.publicEmptyConstructor = publicEmptyConstructor; + this.noArgumentConstructor = noArgumentConstructor; + this.fragments = fragments; } @Override public Set getImportTypes() { - Set types = new HashSet(); + Set types = new HashSet<>(); for ( MapperReference mapperReference : mapperReferences ) { types.addAll( mapperReference.getImportTypes() ); @@ -73,7 +96,11 @@ public List getAnnotations() { return annotations; } - public boolean isPublicEmptyConstructor() { - return publicEmptyConstructor; + public NoArgumentConstructor getNoArgumentConstructor() { + return noArgumentConstructor; + } + + public Set getFragments() { + return fragments; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedSetter.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedSetter.java new file mode 100644 index 0000000000..8f60b052b9 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotatedSetter.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A method in a generated type that represents a setter with annotations. + * + * @author Lucas Resch + */ +public class AnnotatedSetter extends GeneratedTypeMethod { + + private final Field field; + private final Collection methodAnnotations; + private final Collection parameterAnnotations; + + public AnnotatedSetter(Field field, Collection methodAnnotations, + Collection parameterAnnotations) { + this.field = field; + this.methodAnnotations = methodAnnotations; + this.parameterAnnotations = parameterAnnotations; + } + + @Override + public Set getImportTypes() { + Set importTypes = new HashSet<>( field.getImportTypes() ); + for ( Annotation annotation : methodAnnotations ) { + importTypes.addAll( annotation.getImportTypes() ); + } + + for ( Annotation annotation : parameterAnnotations ) { + importTypes.addAll( annotation.getImportTypes() ); + } + + return importTypes; + } + + public Type getType() { + return field.getType(); + } + + public String getFieldName() { + return field.getVariableName(); + } + + public Collection getMethodAnnotations() { + return methodAnnotations; + } + + public Collection getParameterAnnotations() { + return parameterAnnotations; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Annotation.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Annotation.java index dddef0a3a2..866012c51a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Annotation.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Annotation.java @@ -1,27 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Set; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Type; @@ -34,16 +23,13 @@ public class Annotation extends ModelElement { private final Type type; - /** - * List of annotation attributes. Quite simplistic, but it's sufficient for now. - */ - private List properties; + private List properties; public Annotation(Type type) { - this( type, Collections.emptyList() ); + this( type, Collections.emptyList() ); } - public Annotation(Type type, List properties) { + public Annotation(Type type, List properties) { this.type = type; this.properties = properties; } @@ -54,10 +40,15 @@ public Type getType() { @Override public Set getImportTypes() { - return Collections.singleton( type ); + Set types = new HashSet<>(); + for ( AnnotationElement prop : properties ) { + types.addAll( prop.getImportTypes() ); + } + types.add( type ); + return types; } - public List getProperties() { + public List getProperties() { return properties; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotationMapperReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotationMapperReference.java index 88d8dbe294..4cb78ea4f8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotationMapperReference.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/AnnotationMapperReference.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -55,7 +42,7 @@ public List getAnnotations() { @Override public Set getImportTypes() { - Set types = new HashSet(); + Set types = new HashSet<>(); types.add( getType() ); for ( Annotation annotation : annotations ) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index 090ac070b1..080eab1e76 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; @@ -29,42 +14,73 @@ import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Set; - +import java.util.function.Supplier; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.ElementFilter; import javax.tools.Diagnostic; +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; import org.mapstruct.ap.internal.model.PropertyMapping.ConstantMappingBuilder; import org.mapstruct.ap.internal.model.PropertyMapping.JavaExpressionMappingBuilder; import org.mapstruct.ap.internal.model.PropertyMapping.PropertyMappingBuilder; +import org.mapstruct.ap.internal.model.beanmapping.MappingReference; +import org.mapstruct.ap.internal.model.beanmapping.MappingReferences; +import org.mapstruct.ap.internal.model.beanmapping.SourceReference; +import org.mapstruct.ap.internal.model.beanmapping.TargetReference; +import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.BuilderType; +import org.mapstruct.ap.internal.model.common.FormattingParameters; +import org.mapstruct.ap.internal.model.common.NewInstanceCreation; import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.ParameterBinding; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer; import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer.GraphAnalyzerBuilder; -import org.mapstruct.ap.internal.model.source.BeanMapping; -import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; -import org.mapstruct.ap.internal.model.source.Mapping; +import org.mapstruct.ap.internal.model.source.BeanMappingOptions; import org.mapstruct.ap.internal.model.source.MappingOptions; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.model.source.PropertyEntry; import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.model.source.SourceMethod; -import org.mapstruct.ap.internal.model.source.SourceReference; -import org.mapstruct.ap.internal.model.source.TargetReference; -import org.mapstruct.ap.internal.prism.BeanMappingPrism; -import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; -import org.mapstruct.ap.internal.prism.ReportingPolicyPrism; -import org.mapstruct.ap.internal.util.MapperConfiguration; +import org.mapstruct.ap.internal.model.source.SubclassMappingOptions; +import org.mapstruct.ap.internal.model.source.selector.SelectedMethod; +import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; +import org.mapstruct.ap.internal.util.accessor.AccessorType; +import org.mapstruct.ap.internal.util.accessor.ElementAccessor; +import org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; +import org.mapstruct.ap.internal.util.kotlin.KotlinMetadata; + +import static org.mapstruct.ap.internal.model.beanmapping.MappingReferences.forSourceMethod; +import static org.mapstruct.ap.internal.util.Collections.first; +import static org.mapstruct.ap.internal.util.Message.BEANMAPPING_ABSTRACT; +import static org.mapstruct.ap.internal.util.Message.BEANMAPPING_NOT_ASSIGNABLE; +import static org.mapstruct.ap.internal.util.Message.GENERAL_ABSTRACT_RETURN_TYPE; +import static org.mapstruct.ap.internal.util.Message.GENERAL_AMBIGUOUS_CONSTRUCTORS; +import static org.mapstruct.ap.internal.util.Message.GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS; +import static org.mapstruct.ap.internal.util.Message.PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET; +import static org.mapstruct.ap.internal.util.Message.PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET; /** * A {@link MappingMethod} implemented by a {@link Mapper} class which maps one bean type to another, optionally @@ -76,230 +92,644 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { private final List propertyMappings; private final Map> mappingsByParameter; + private final Map> constructorMappingsByParameter; + private final Map presenceChecksByParameter; private final List constantMappings; - private final Type resultType; + private final List constructorConstantMappings; + private final List subclassMappings; + private final Type returnTypeToConstruct; + private final NewInstanceCreation newInstance; + private final BuilderType returnTypeBuilder; private final MethodReference finalizerMethod; + private final String finalizedResultName; + private final String optionalResultName; + private final List beforeMappingReferencesWithFinalizedReturnType; + private final List afterMappingReferencesWithFinalizedReturnType; + private final List afterMappingReferencesWithOptionalReturnType; + private final Type subclassExhaustiveException; + private final Map sourceParametersReassignments; + + private final MappingReferences mappingReferences; - public static class Builder { + public static class Builder extends AbstractMappingMethodBuilder { - private MappingBuilderContext ctx; - private Method method; + /* returnType to construct can have a builder */ + private BuilderType returnTypeBuilder; + private Map unprocessedConstructorProperties; private Map unprocessedTargetProperties; private Map unprocessedSourceProperties; + private Set missingIgnoredSourceProperties; + private Set redundantIgnoredSourceProperties; private Set targetProperties; - private final List propertyMappings = new ArrayList(); - private final Set unprocessedSourceParameters = new HashSet(); - private NullValueMappingStrategyPrism nullValueMappingStrategy; - private SelectionParameters selectionParameters; - private final Set existingVariableNames = new HashSet(); - private Map> methodMappings; - private SingleMappingByTargetPropertyNameFunction singleMapping; - private final Map> unprocessedDefinedTargets = new HashMap>(); - - public Builder mappingContext(MappingBuilderContext mappingContext) { - this.ctx = mappingContext; - return this; + private final List propertyMappings = new ArrayList<>(); + private final Set unprocessedSourceParameters = new HashSet<>(); + private final Set existingVariableNames = new HashSet<>(); + private final Map> unprocessedDefinedTargets = new LinkedHashMap<>(); + private final Map sourceParametersReassignments = new HashMap<>(); + + private MappingReferences mappingReferences; + private List targetThisReferences; + private MethodReference factoryMethod; + private boolean hasFactoryMethod; + + public Builder() { + super( Builder.class ); + } + + @Override + protected boolean shouldUsePropertyNamesInHistory() { + return true; } public Builder sourceMethod(SourceMethod sourceMethod) { - singleMapping = new SourceMethodSingleMapping( sourceMethod ); - return setupMethodWithMapping( sourceMethod ); + method( sourceMethod ); + return this; } - public Builder forgedMethod(Method method) { - singleMapping = new EmptySingleMapping(); - return setupMethodWithMapping( method ); + public Builder forgedMethod(ForgedMethod forgedMethod) { + method( forgedMethod ); + mappingReferences = forgedMethod.getMappingReferences(); + Parameter sourceParameter = first( Parameter.getSourceParameters( forgedMethod.getParameters() ) ); + for ( MappingReference mappingReference : mappingReferences.getMappingReferences() ) { + SourceReference sourceReference = mappingReference.getSourceReference(); + if ( sourceReference != null ) { + mappingReference.setSourceReference( new SourceReference.BuilderFromSourceReference() + .sourceParameter( sourceParameter ) + .sourceReference( sourceReference ) + .build() ); + } + } + return this; } - private Builder setupMethodWithMapping(Method sourceMethod) { - this.method = sourceMethod; - this.methodMappings = sourceMethod.getMappingOptions().getMappings(); - CollectionMappingStrategyPrism cms = sourceMethod.getMapperConfiguration().getCollectionMappingStrategy(); - Type mappingType = method.getResultType(); - if ( !method.isUpdateMethod() ) { - mappingType = mappingType.getEffectiveType(); + @Override + public BeanMappingMethod build() { + + BeanMappingOptions beanMapping = method.getOptions().getBeanMapping(); + SelectionParameters selectionParameters = beanMapping != null ? beanMapping.getSelectionParameters() : null; + + /* the return type that needs to be constructed (new or factorized), so for instance: */ + /* 1) the return type of a non-update method */ + /* 2) or the implementation type that needs to be used when the return type is abstract */ + /* 3) or the builder whenever the return type is immutable */ + Type returnTypeToConstruct = null; + + // determine which return type to construct + boolean cannotConstructReturnType = false; + if ( !method.getReturnType().isVoid() ) { + BuilderGem builder = method.getOptions().getBeanMapping().getBuilder(); + Type returnTypeImpl; + Type userDefinedReturnType = null; + if ( selectionParameters != null && selectionParameters.getResultType() != null ) { + // This is a user-defined return type, which means we need to do some extra checks for it + userDefinedReturnType = ctx.getTypeFactory().getType( selectionParameters.getResultType() ); + returnTypeImpl = userDefinedReturnType; + returnTypeBuilder = ctx.getTypeFactory().builderTypeFor( userDefinedReturnType, builder ); + } + else { + Type methodReturnType = method.getReturnType(); + if ( methodReturnType.isOptionalType() ) { + returnTypeImpl = methodReturnType.getOptionalBaseType(); + } + else { + returnTypeImpl = methodReturnType; + } + returnTypeBuilder = ctx.getTypeFactory().builderTypeFor( returnTypeImpl, builder ); + } + if ( isBuilderRequired() ) { + // the userDefinedReturn type can also require a builder. That buildertype is already set + returnTypeImpl = returnTypeBuilder.getBuilder(); + initializeFactoryMethod( returnTypeImpl, selectionParameters ); + if ( factoryMethod != null + || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) + || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { + returnTypeToConstruct = returnTypeImpl; + } + else { + cannotConstructReturnType = true; + } + } + else if ( userDefinedReturnType != null ) { + initializeFactoryMethod( returnTypeImpl, selectionParameters ); + if ( factoryMethod != null || canResultTypeFromBeanMappingBeConstructed( returnTypeImpl ) ) { + returnTypeToConstruct = returnTypeImpl; + } + else { + cannotConstructReturnType = true; + } + } + else if ( !method.isUpdateMethod() ) { + initializeFactoryMethod( returnTypeImpl, selectionParameters ); + if ( factoryMethod != null + || allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed( returnTypeImpl ) + || doesNotAllowAbstractReturnTypeAndCanBeConstructed( returnTypeImpl ) ) { + returnTypeToConstruct = returnTypeImpl; + } + else { + cannotConstructReturnType = true; + } + } } - Map accessors = mappingType - .getPropertyWriteAccessors( cms ); - this.targetProperties = accessors.keySet(); + if ( cannotConstructReturnType ) { + // If the return type cannot be constructed then no need to try to create mappings + return null; + } + + /* the type that needs to be used in the mapping process as target */ + Type resultTypeToMap = returnTypeToConstruct == null ? method.getResultType() : returnTypeToConstruct; + + existingVariableNames.addAll( method.getParameterNames() ); + + CollectionMappingStrategyGem cms = this.method.getOptions().getMapper().getCollectionMappingStrategy(); + + // determine accessors + Map accessors = resultTypeToMap.getPropertyWriteAccessors( cms ); + this.targetProperties = new LinkedHashSet<>( accessors.keySet() ); + + this.unprocessedTargetProperties = new LinkedHashMap<>( accessors ); + + boolean constructorAccessorHadError = false; + if ( !method.isUpdateMethod() && !hasFactoryMethod ) { + ConstructorAccessor constructorAccessor = getConstructorAccessor( resultTypeToMap ); + if ( constructorAccessor != null && !constructorAccessor.hasError ) { + + this.unprocessedConstructorProperties = constructorAccessor.constructorAccessors; + + factoryMethod = MethodReference.forConstructorInvocation( + resultTypeToMap, + constructorAccessor.parameterBindings + ); + + } + else { + this.unprocessedConstructorProperties = new LinkedHashMap<>(); + } + constructorAccessorHadError = constructorAccessor != null && constructorAccessor.hasError; + + this.targetProperties.addAll( this.unprocessedConstructorProperties.keySet() ); + + this.unprocessedTargetProperties.putAll( this.unprocessedConstructorProperties ); + } + else { + unprocessedConstructorProperties = new LinkedHashMap<>(); + } - this.unprocessedTargetProperties = new LinkedHashMap( accessors ); - this.unprocessedSourceProperties = new LinkedHashMap(); + this.unprocessedSourceProperties = new LinkedHashMap<>(); for ( Parameter sourceParameter : method.getSourceParameters() ) { unprocessedSourceParameters.add( sourceParameter ); - if ( sourceParameter.getType().isPrimitive() ) { - continue; + Type sourceParameterType = sourceParameter.getType(); + if ( sourceParameterType.isOptionalType() ) { + String sourceParameterValueName = Strings.getSafeVariableName( + sourceParameter.getName() + "Value", + existingVariableNames + ); + existingVariableNames.add( sourceParameterValueName ); + sourceParameterType = sourceParameterType.getOptionalBaseType(); + sourceParametersReassignments.put( + sourceParameter.getName(), + new Parameter( sourceParameterValueName, sourceParameter.getName(), sourceParameterType ) + ); } - Map readAccessors = sourceParameter.getType().getPropertyReadAccessors(); - for ( String key : readAccessors.keySet() ) { - unprocessedSourceProperties.put( key, readAccessors.get( key ) ); + if ( sourceParameterType.isPrimitive() || sourceParameterType.isArrayType() || + sourceParameterType.isMapType() ) { + continue; } + + Map readAccessors = sourceParameterType.getPropertyReadAccessors(); + + unprocessedSourceProperties.putAll( readAccessors ); } - existingVariableNames.addAll( method.getParameterNames() ); - BeanMapping beanMapping = method.getMappingOptions().getBeanMapping(); - if ( beanMapping != null ) { + // get bean mapping (when specified as annotation ) + this.missingIgnoredSourceProperties = new LinkedHashSet<>(); + this.redundantIgnoredSourceProperties = new LinkedHashSet<>(); + if ( beanMapping != null && !beanMapping.getIgnoreUnmappedSourceProperties().isEmpty() ) { + // Get source properties explicitly mapped using @Mapping annotations + Set mappedSourceProperties = method.getOptions().getMappings().stream() + .map( MappingOptions::getSourceName ) + .filter( Objects::nonNull ) + .collect( Collectors.toSet() ); + for ( String ignoreUnmapped : beanMapping.getIgnoreUnmappedSourceProperties() ) { - unprocessedSourceProperties.remove( ignoreUnmapped ); + // Track missing ignored properties (i.e. not in source class) + if ( unprocessedSourceProperties.remove( ignoreUnmapped ) == null ) { + missingIgnoredSourceProperties.add( ignoreUnmapped ); + } + // Track redundant ignored properties (actually mapped despite being ignored) + if ( mappedSourceProperties.contains( ignoreUnmapped ) ) { + redundantIgnoredSourceProperties.add( ignoreUnmapped ); + } } } - return this; - } + initializeMappingReferencesIfNeeded( resultTypeToMap ); - public Builder selectionParameters(SelectionParameters selectionParameters) { - this.selectionParameters = selectionParameters; - return this; - } + boolean shouldHandledDefinedMappings = shouldHandledDefinedMappings( resultTypeToMap ); - public Builder nullValueMappingStrategy(NullValueMappingStrategyPrism nullValueMappingStrategy) { - this.nullValueMappingStrategy = nullValueMappingStrategy; - return this; - } - public BeanMappingMethod build() { - // map properties with mapping - boolean mappingErrorOccured = handleDefinedMappings(); - if ( mappingErrorOccured ) { - return null; + if ( shouldHandledDefinedMappings ) { + // map properties with mapping + boolean mappingErrorOccurred = handleDefinedMappings( resultTypeToMap ); + if ( mappingErrorOccurred ) { + return null; + } + } + + // If defined mappings should not be handled then we should not apply implicit mappings + boolean applyImplicitMappings = + shouldHandledDefinedMappings && !mappingReferences.isRestrictToDefinedMappings(); + if ( applyImplicitMappings ) { + applyImplicitMappings = beanMapping == null || !beanMapping.isIgnoredByDefault(); } + if ( applyImplicitMappings ) { - if ( !method.getMappingOptions().isRestrictToDefinedMappings() ) { + // apply name based mapping from a source reference + applyTargetThisMapping(); // map properties without a mapping applyPropertyNameBasedMapping(); // map parameters without a mapping applyParameterNameBasedMapping(); + } // Process the unprocessed defined targets handleUnprocessedDefinedTargets(); + // Initialize unprocessed constructor properties + handleUnmappedConstructorProperties(); + // report errors on unmapped properties - reportErrorForUnmappedTargetPropertiesIfRequired(); - reportErrorForUnmappedSourcePropertiesIfRequired(); + if ( shouldHandledDefinedMappings ) { + reportErrorForUnmappedTargetPropertiesIfRequired( resultTypeToMap, constructorAccessorHadError ); + reportErrorForUnmappedSourcePropertiesIfRequired(); + } + reportErrorForMissingIgnoredSourceProperties(); + reportErrorForUnusedSourceParameters(); + reportErrorForRedundantIgnoredSourceProperties(); - // mapNullToDefault - boolean mapNullToDefault = method.getMapperConfiguration().isMapToDefault( nullValueMappingStrategy ); + // mapNullToDefault — JSpecify @NonNull return forces RETURN_DEFAULT to avoid generating `return null`. + boolean mapNullToDefault = method.getOptions() + .getBeanMapping() + .getNullValueMappingStrategy() + .isReturnDefault(); + // sort + sortPropertyMappingsByDependencies(); - BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() ); + // before / after mappings + List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( + method, + resultTypeToMap, + selectionParameters, + ctx, + existingVariableNames + ); - MethodReference factoryMethod = null; - if ( !method.isUpdateMethod() ) { - factoryMethod = ObjectFactoryMethodResolver.getFactoryMethod( - method, - method.getResultType(), - selectionParameters, - ctx - ); - } + Supplier> additionalAfterMappingParameterBindingsProvider = () -> + sourceParametersReassignments.values() + .stream() + .map( parameter -> method.getSourceParameters().size() == 1 ? + ParameterBinding.fromParameter( parameter ) : + ParameterBinding.fromTypeAndName( + parameter.getType(), + parameter.getOriginalName() + ".get()" + ) ) + .collect( Collectors.toList() ); + List afterMappingMethods = LifecycleMethodResolver.afterMappingMethods( + method, + resultTypeToMap, + selectionParameters, + ctx, + existingVariableNames, + Collections::emptyList + ); - // if there's no factory method, try the resultType in the @BeanMapping - Type resultType = null; - if ( factoryMethod == null ) { - if ( selectionParameters != null && selectionParameters.getResultType() != null ) { - resultType = ctx.getTypeFactory().getType( selectionParameters.getResultType() ).getEffectiveType(); - if ( resultType.isAbstract() ) { - ctx.getMessager().printMessage( - method.getExecutable(), - beanMappingPrism.mirror, - Message.BEANMAPPING_ABSTRACT, - resultType, - method.getResultType() - ); - } - else if ( !resultType.isAssignableTo( method.getResultType() ) ) { - ctx.getMessager().printMessage( - method.getExecutable(), - beanMappingPrism.mirror, - Message.BEANMAPPING_NOT_ASSIGNABLE, resultType, method.getResultType() - ); - } - else if ( !resultType.hasEmptyAccessibleContructor() ) { - ctx.getMessager().printMessage( - method.getExecutable(), - beanMappingPrism.mirror, - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - resultType - ); - } + if ( method instanceof ForgedMethod ) { + ForgedMethod forgedMethod = (ForgedMethod) method; + if ( factoryMethod != null ) { + forgedMethod.addThrownTypes( factoryMethod.getThrownTypes() ); } - else if ( !method.isUpdateMethod() && method.getReturnType().getEffectiveType().isAbstract() ) { - ctx.getMessager().printMessage( - method.getExecutable(), - Message.GENERAL_ABSTRACT_RETURN_TYPE, - method.getReturnType().getEffectiveType() - ); + for ( LifecycleCallbackMethodReference beforeMappingMethod : beforeMappingMethods ) { + forgedMethod.addThrownTypes( beforeMappingMethod.getThrownTypes() ); } - else if ( !method.isUpdateMethod() && - !method.getReturnType().getEffectiveType().hasEmptyAccessibleContructor() ) { - ctx.getMessager().printMessage( - method.getExecutable(), - Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, - method.getReturnType().getEffectiveType() - ); + + for ( LifecycleCallbackMethodReference afterMappingMethod : afterMappingMethods ) { + forgedMethod.addThrownTypes( afterMappingMethod.getThrownTypes() ); + } + + + for ( PropertyMapping propertyMapping : propertyMappings ) { + if ( propertyMapping.getAssignment() != null ) { + forgedMethod.addThrownTypes( propertyMapping.getAssignment().getThrownTypes() ); + } } + } - sortPropertyMappingsByDependencies(); + TypeMirror subclassExhaustiveException = method.getOptions() + .getBeanMapping() + .getSubclassExhaustiveException(); + Type subclassExhaustiveExceptionType = ctx.getTypeFactory().getType( subclassExhaustiveException ); - List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( - method, - selectionParameters, - ctx, - existingVariableNames - ); - List afterMappingMethods = - LifecycleMethodResolver.afterMappingMethods( method, selectionParameters, ctx, existingVariableNames ); + List subclasses = new ArrayList<>(); + for ( SubclassMappingOptions subclassMappingOptions : method.getOptions().getSubclassMappings() ) { + subclasses.add( createSubclassMapping( subclassMappingOptions ) ); + } + + MethodReference finalizeMethod = null; + + List beforeMappingReferencesWithFinalizedReturnType = new ArrayList<>(); + List afterMappingReferencesWithFinalizedReturnType = new ArrayList<>(); + if ( shouldCallFinalizerMethod( returnTypeToConstruct ) ) { + finalizeMethod = getFinalizerMethod(); + + Type finalizerReturnType = method.getReturnType(); + if ( finalizerReturnType.isOptionalType() ) { + finalizerReturnType = finalizerReturnType.getOptionalBaseType(); + } + + beforeMappingReferencesWithFinalizedReturnType.addAll( filterMappingTarget( + LifecycleMethodResolver.beforeMappingMethods( + method, + finalizerReturnType, + selectionParameters, + ctx, + existingVariableNames + ), + false + ) ); + + afterMappingReferencesWithFinalizedReturnType.addAll( LifecycleMethodResolver.afterMappingMethods( + method, + finalizerReturnType, + selectionParameters, + ctx, + existingVariableNames, + additionalAfterMappingParameterBindingsProvider + ) ); - if (factoryMethod != null && method instanceof ForgedMethod ) { - ( (ForgedMethod) method ).addThrownTypes( factoryMethod.getThrownTypes() ); + keepMappingReferencesUsingTarget( beforeMappingReferencesWithFinalizedReturnType, finalizerReturnType ); + keepMappingReferencesUsingTarget( afterMappingReferencesWithFinalizedReturnType, finalizerReturnType ); } - MethodReference finalizeMethod = getFinalizerMethod( - resultType == null ? method.getReturnType() : resultType ); + List afterMappingReferencesWithOptionalReturnType = new ArrayList<>(); + if ( method.getReturnType().isOptionalType() ) { + afterMappingReferencesWithOptionalReturnType.addAll( LifecycleMethodResolver.afterMappingMethods( + method, + method.getReturnType(), + selectionParameters, + ctx, + existingVariableNames, + additionalAfterMappingParameterBindingsProvider + ) ); + + keepMappingReferencesUsingTarget( + afterMappingReferencesWithOptionalReturnType, + method.getReturnType() + ); + + } + + Map presenceChecksByParameter = new LinkedHashMap<>(); + for ( Parameter sourceParameter : method.getSourceParameters() ) { + PresenceCheck parameterPresenceCheck = PresenceCheckMethodResolver.getPresenceCheckForSourceParameter( + method, + selectionParameters, + sourceParameter, + ctx + ); + if ( parameterPresenceCheck != null ) { + presenceChecksByParameter.put( sourceParameter.getName(), parameterPresenceCheck ); + } + } + + // JSpecify: a @NonNull return forces RETURN_DEFAULT to avoid generating `return null`. + // The extra presence-check guard is bean-specific and required for correctness, not just an + // optimization: the bean template only emits a `return null` (and the presence-check wrapping that + // forcing mapNullToDefault would alter) when there are nullable source parameters. With none, + // getPresenceCheckByParameter would resolve to null in the single-source template branches. + // Container/Map/Stream methods instead gate this in their templates via `sourceParameterPresenceCheck??`, + // so they force unconditionally. + if ( !mapNullToDefault + && !presenceChecksByParameter.isEmpty() + && ctx.isJSpecifyNonNullReturn( method ) ) { + ctx.getMessager().note( 2, + Message.MAPPING_METHOD_JSPECIFY_FORCE_RETURN_DEFAULT, + method.getName() ); + mapNullToDefault = true; + } return new BeanMappingMethod( method, + getMethodAnnotations(), existingVariableNames, propertyMappings, factoryMethod, mapNullToDefault, - resultType, + returnTypeToConstruct, + returnTypeBuilder, beforeMappingMethods, afterMappingMethods, - finalizeMethod + beforeMappingReferencesWithFinalizedReturnType, + afterMappingReferencesWithFinalizedReturnType, + afterMappingReferencesWithOptionalReturnType, + finalizeMethod, + mappingReferences, + subclasses, + presenceChecksByParameter, + subclassExhaustiveExceptionType, + sourceParametersReassignments ); } - private MethodReference getFinalizerMethod(Type resultType) { - if ( method.getReturnType().isVoid() || - resultType.getEffectiveType().isAssignableTo( resultType ) ) { - return null; + private void keepMappingReferencesUsingTarget(List references, Type type) { + references.removeIf( reference -> { + List bindings = reference.getParameterBindings(); + if ( bindings.isEmpty() ) { + return true; + } + for ( ParameterBinding binding : bindings ) { + if ( binding.isMappingTarget() ) { + if ( type.isAssignableTo( binding.getType() ) ) { + // If the mapping target matches the type then we need to keep this + return false; + } + } + else if ( binding.isTargetType() ) { + Type targetType = binding.getType(); + List targetTypeTypeParameters = targetType.getTypeParameters(); + if ( targetTypeTypeParameters.size() == 1 ) { + if ( type.isAssignableTo( targetTypeTypeParameters.get( 0 ) ) ) { + return false; + } + } + } + } + + return true; + } ); + } + + private boolean doesNotAllowAbstractReturnTypeAndCanBeConstructed(Type returnTypeImpl) { + return !isAbstractReturnTypeAllowed() + && canReturnTypeBeConstructed( returnTypeImpl ); + } + + private boolean allowsAbstractReturnTypeAndIsEitherAbstractOrCanBeConstructed(Type returnTypeImpl) { + return isAbstractReturnTypeAllowed() + && isReturnTypeAbstractOrCanBeConstructed( returnTypeImpl ); + } + + private SubclassMapping createSubclassMapping(SubclassMappingOptions subclassMappingOptions) { + TypeFactory typeFactory = ctx.getTypeFactory(); + Type sourceType = typeFactory.getType( subclassMappingOptions.getSource() ); + Type targetType = typeFactory.getType( subclassMappingOptions.getTarget() ); + + SourceRHS rightHandSide = new SourceRHS( + "subclassMapping", + sourceType, + Collections.emptySet(), + "SubclassMapping for " + sourceType.getFullyQualifiedName() ); + SelectionCriteria criteria = + SelectionCriteria + .forSubclassMappingMethods( + subclassMappingOptions.getSelectionParameters().withSourceRHS( rightHandSide ), + subclassMappingOptions.getMappingControl( ctx.getElementUtils() ) + ); + Assignment assignment = ctx + .getMappingResolver() + .getTargetAssignment( + method, + null, + targetType, + FormattingParameters.EMPTY, + criteria, + rightHandSide, + subclassMappingOptions.getMirror(), + () -> forgeSubclassMapping( + rightHandSide, + sourceType, + targetType, + mappingReferences ) ); + String sourceArgument = null; + for ( Parameter parameter : method.getSourceParameters() ) { + if ( ctx + .getTypeUtils() + .isAssignable( sourceType.getTypeMirror(), parameter.getType().getTypeMirror() ) ) { + sourceArgument = parameter.getName(); + if ( assignment != null ) { + assignment.setSourceLocalVarName( + "(" + sourceType.createReferenceName() + ") " + sourceArgument ); + } + } } - BuilderType builderType = resultType.getBuilderType(); - if ( builderType == null ) { - // If the mapping type is assignable to the result type this should never happen - return null; + return new SubclassMapping( sourceType, sourceArgument, targetType, assignment ); + } + + private boolean isAbstractReturnTypeAllowed() { + return !method.getOptions().getSubclassMappings().isEmpty() + && ( method.getOptions().getBeanMapping().getSubclassExhaustiveStrategy().isAbstractReturnTypeAllowed() + || isCorrectlySealed() ); + } + + private boolean isCorrectlySealed() { + Type mappingSourceType = method.getMappingSourceType(); + return isCorrectlySealed( mappingSourceType ); + } + + private boolean isCorrectlySealed(Type mappingSourceType) { + if ( mappingSourceType.isSealed() ) { + List unusedPermittedSubclasses = + new ArrayList<>( mappingSourceType.getPermittedSubclasses() ); + method.getOptions().getSubclassMappings().forEach( subClassOption -> { + for ( Iterator iterator = unusedPermittedSubclasses.iterator(); + iterator.hasNext(); ) { + if ( ctx.getTypeUtils().isSameType( iterator.next(), subClassOption.getSource() ) ) { + iterator.remove(); + } + } + } ); + for ( Iterator iterator = unusedPermittedSubclasses.iterator(); + iterator.hasNext(); ) { + TypeMirror typeMirror = iterator.next(); + Type type = ctx.getTypeFactory().getType( typeMirror ); + if ( type.isAbstract() && isCorrectlySealed( type ) ) { + iterator.remove(); + } + } + return unusedPermittedSubclasses.isEmpty(); + } + return false; + } + + private void initializeMappingReferencesIfNeeded(Type resultTypeToMap) { + if ( mappingReferences == null && method instanceof SourceMethod ) { + Set readAndWriteTargetProperties = new HashSet<>( unprocessedTargetProperties.keySet() ); + readAndWriteTargetProperties.addAll( resultTypeToMap.getPropertyReadAccessors().keySet() ); + mappingReferences = forSourceMethod( + (SourceMethod) method, + resultTypeToMap, + readAndWriteTargetProperties, + ctx.getMessager(), + ctx.getTypeFactory() + ); + } + } + + /** + * @return builder is required when there is a returnTypeBuilder and the mapping method is not update method. + * However, builder is also required when there is a returnTypeBuilder, the mapping target is the builder and + * builder is not assignable to the return type (so without building). + */ + private boolean isBuilderRequired() { + if ( returnTypeBuilder == null ) { + return false; + } + if ( method.isUpdateMethod() ) { + // when @MappingTarget annotated parameter is the same type as the return type. + return !method.getResultType().isAssignableTo( method.getReturnType() ); + } + else { + // For non-update methods a builder is required when returnTypeBuilder is set + return true; + } + } + + private boolean shouldCallFinalizerMethod(Type returnTypeToConstruct ) { + if ( returnTypeToConstruct == null ) { + return false; + } + else if ( returnTypeToConstruct.isAssignableTo( method.getReturnType() ) ) { + // If the mapping type can be assigned to the return type then we + // don't need a finalizer method + return false; } - return BuilderFinisherMethodResolver.getBuilderFinisherMethod( method, builderType, ctx ); + return returnTypeBuilder != null; + } + + private MethodReference getFinalizerMethod() { + return BuilderFinisherMethodResolver.getBuilderFinisherMethod( + method, + returnTypeBuilder, + ctx + ); } /** * If there were nested defined targets that have not been handled. Then we need to process them at the end. */ private void handleUnprocessedDefinedTargets() { - Iterator>> iterator = unprocessedDefinedTargets.entrySet().iterator(); + Iterator>> iterator = unprocessedDefinedTargets.entrySet().iterator(); // For each of the unprocessed defined targets forge a mapping for each of the // method source parameters. The generated mappings are not going to use forged name based mappings. while ( iterator.hasNext() ) { - Entry> entry = iterator.next(); + Entry> entry = iterator.next(); String propertyName = entry.getKey(); if ( !unprocessedTargetProperties.containsKey( propertyName ) ) { continue; @@ -312,31 +742,60 @@ private void handleUnprocessedDefinedTargets() { .name( propertyName ) .build(); - MappingOptions mappingOptions = extractAdditionalOptions( propertyName, true ); + ReadAccessor targetPropertyReadAccessor = + method.getResultType().getReadAccessor( propertyName, forceUpdateMethod ); + MappingReferences mappingRefs = extractMappingReferences( propertyName, true ); PropertyMapping propertyMapping = new PropertyMappingBuilder() .mappingContext( ctx ) .sourceMethod( method ) - .targetWriteAccessor( unprocessedTargetProperties.get( propertyName ) ) - .targetReadAccessor( getTargetPropertyReadAccessor( propertyName ) ) - .targetPropertyName( propertyName ) + .target( + propertyName, + targetPropertyReadAccessor, + unprocessedTargetProperties.get( propertyName ) + ) .sourceReference( reference ) .existingVariableNames( existingVariableNames ) - .dependsOn( mappingOptions.collectNestedDependsOn() ) - .forgeMethodWithMappingOptions( mappingOptions ) + .dependsOn( mappingRefs.collectNestedDependsOn() ) + .forgeMethodWithMappingReferences( mappingRefs ) .forceUpdateMethod( forceUpdateMethod ) .forgedNamedBased( false ) .build(); if ( propertyMapping != null ) { unprocessedTargetProperties.remove( propertyName ); + unprocessedConstructorProperties.remove( propertyName ); unprocessedSourceProperties.remove( propertyName ); iterator.remove(); propertyMappings.add( propertyMapping ); + // If we found a mapping for the unprocessed property then stop + break; } } } } + private void handleUnmappedConstructorProperties() { + for ( Entry entry : unprocessedConstructorProperties.entrySet() ) { + Accessor accessor = entry.getValue(); + Type accessedType = ctx.getTypeFactory() + .getType( accessor.getAccessedType() ); + String targetPropertyName = entry.getKey(); + + propertyMappings.add( new JavaExpressionMappingBuilder() + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( accessedType.getNull() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, null, accessor ) + .dependsOn( Collections.emptySet() ) + .mirror( null ) + .build() + ); + } + + unprocessedConstructorProperties.clear(); + } + /** * Sources the given mappings as per the dependency relationships given via {@code dependsOn()}. If a cycle is * detected, an error is reported. @@ -351,7 +810,7 @@ private void sortPropertyMappingsByDependencies() { final GraphAnalyzer graphAnalyzer = graphAnalyzerBuilder.build(); if ( !graphAnalyzer.getCycles().isEmpty() ) { - Set cycles = new HashSet(); + Set cycles = new HashSet<>(); for ( List cycle : graphAnalyzer.getCycles() ) { cycles.add( Strings.join( cycle, " -> " ) ); } @@ -362,18 +821,440 @@ private void sortPropertyMappingsByDependencies() { ); } else { - Collections.sort( - propertyMappings, new Comparator() { - @Override - public int compare(PropertyMapping o1, PropertyMapping o2) { - return graphAnalyzer.getTraversalSequence( o1.getName() ) - - graphAnalyzer.getTraversalSequence( o2.getName() ); + propertyMappings.sort( Comparator.comparingInt( propertyMapping -> + graphAnalyzer.getTraversalSequence( propertyMapping.getName() ) ) ); + } + } + + private boolean canResultTypeFromBeanMappingBeConstructed(Type resultType) { + + boolean error = true; + if ( resultType.isAbstract() ) { + ctx.getMessager().printMessage( + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + BEANMAPPING_ABSTRACT, + resultType.describe(), + method.getResultType().describe() + ); + error = false; + } + else if ( !resultType.isAssignableTo( method.getResultType() ) ) { + ctx.getMessager().printMessage( + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + BEANMAPPING_NOT_ASSIGNABLE, + resultType.describe(), + method.getResultType().describe() + ); + error = false; + } + else if ( !resultType.hasAccessibleConstructor() ) { + ctx.getMessager().printMessage( + method.getExecutable(), + method.getOptions().getBeanMapping().getMirror(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + resultType.describe() + ); + error = false; + } + return error; + } + + private boolean canReturnTypeBeConstructed(Type returnType) { + boolean error = true; + if ( returnType.isAbstract() ) { + ctx.getMessager().printMessage( + method.getExecutable(), + GENERAL_ABSTRACT_RETURN_TYPE, + returnType.describe() + ); + error = false; + } + else if ( !returnType.hasAccessibleConstructor() ) { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + returnType.describe() + ); + error = false; + } + return error; + } + + private boolean isReturnTypeAbstractOrCanBeConstructed(Type returnType) { + boolean error = true; + if ( !returnType.isAbstract() && !returnType.hasAccessibleConstructor() ) { + ctx + .getMessager() + .printMessage( + method.getExecutable(), + Message.GENERAL_NO_SUITABLE_CONSTRUCTOR, + returnType.describe() ); + error = false; + } + return error; + } + + /** + * Find a factory method for a return type or for a builder. + * @param returnTypeImpl the return type implementation to construct + * @param @selectionParameters + */ + private void initializeFactoryMethod(Type returnTypeImpl, SelectionParameters selectionParameters) { + List> matchingFactoryMethods = + ObjectFactoryMethodResolver.getMatchingFactoryMethods( + method, + returnTypeImpl, + selectionParameters, + ctx + ); + + if ( matchingFactoryMethods.isEmpty() ) { + if ( factoryMethod == null && returnTypeBuilder != null ) { + factoryMethod = ObjectFactoryMethodResolver.getBuilderFactoryMethod( method, returnTypeBuilder ); + hasFactoryMethod = factoryMethod != null; + } + } + else if ( matchingFactoryMethods.size() == 1 ) { + factoryMethod = ObjectFactoryMethodResolver.getFactoryMethodReference( + method, + first( matchingFactoryMethods ), + ctx + ); + hasFactoryMethod = true; + } + else { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, + returnTypeImpl.describe(), + matchingFactoryMethods.stream() + .map( SelectedMethod::getMethod ) + .map( Method::describe ) + .collect( Collectors.joining( ", " ) ) + ); + hasFactoryMethod = true; + } + } + + private ConstructorAccessor getConstructorAccessor(Type type) { + if ( type.isAbstract() ) { + // We cannot construct abstract classes. + // Usually we won't reach here, + // but if SubclassMapping is used with SubclassExhaustiveStrategy#RUNTIME_EXCEPTION + // then we will still generate the code. + // We shouldn't generate anything for those abstract types + return null; + } + + if ( type.isRecord() ) { + + List constructors = ElementFilter.constructorsIn( type.getTypeElement() + .getEnclosedElements() ); + + for ( ExecutableElement constructor : constructors ) { + if ( constructor.getModifiers().contains( Modifier.PRIVATE ) ) { + continue; + } + + // prefer constructor annotated with @Default + if ( hasDefaultAnnotationFromAnyPackage( constructor ) ) { + return getConstructorAccessor( type, constructor ); + } + } + + + // Other than that, just get the record components and use them + List recordComponents = type.getRecordComponents(); + List parameterBindings = new ArrayList<>( recordComponents.size() ); + Map constructorAccessors = new LinkedHashMap<>(); + for ( Element recordComponent : recordComponents ) { + TypeMirror recordComponentMirror = ctx.getTypeUtils() + .asMemberOf( (DeclaredType) type.getTypeMirror(), recordComponent ); + String parameterName = recordComponent.getSimpleName().toString(); + Accessor accessor = createConstructorAccessor( + recordComponent, + recordComponentMirror, + parameterName + ); + constructorAccessors.put( + parameterName, + accessor + ); + + parameterBindings.add( ParameterBinding.fromTypeAndName( + ctx.getTypeFactory().getType( recordComponentMirror ), + accessor.getSimpleName() + ) ); + } + return new ConstructorAccessor( parameterBindings, constructorAccessors ); + } + + KotlinMetadata kotlinMetadata = type.getKotlinMetadata(); + if ( kotlinMetadata != null && kotlinMetadata.isDataClass() ) { + List constructors = ElementFilter.constructorsIn( type.getTypeElement() + .getEnclosedElements() ); + + Iterator constructorIterator = constructors.iterator(); + while ( constructorIterator.hasNext() ) { + ExecutableElement constructor = constructorIterator.next(); + if ( constructor.getModifiers().contains( Modifier.PRIVATE ) ) { + constructorIterator.remove(); + continue; + } + + // prefer constructor annotated with @Default + if ( hasDefaultAnnotationFromAnyPackage( constructor ) ) { + return getConstructorAccessor( type, constructor ); + } + } + + ExecutableElement primaryConstructor = kotlinMetadata.determinePrimaryConstructor( constructors ); + + return primaryConstructor != null ? getConstructorAccessor( type, primaryConstructor ) : null; + } + + List constructors = ElementFilter.constructorsIn( type.getTypeElement() + .getEnclosedElements() ); + + // The rules for picking a constructor are the following: + // 1. Constructor annotated with @Default (from any package) has highest precedence + // 2. If there is a single public constructor then it would be used to construct the object + // 3. If a parameterless constructor exists then it would be used to construct the object, and the other + // constructors will be ignored + ExecutableElement defaultAnnotatedConstructor = null; + ExecutableElement parameterLessConstructor = null; + List accessibleConstructors = new ArrayList<>( constructors.size() ); + List publicConstructors = new ArrayList<>( ); + + for ( ExecutableElement constructor : constructors ) { + if ( constructor.getModifiers().contains( Modifier.PRIVATE ) ) { + continue; + } + + if ( hasDefaultAnnotationFromAnyPackage( constructor ) ) { + // We found a constructor annotated with @Default everything else is irrelevant + defaultAnnotatedConstructor = constructor; + break; + } + + if ( constructor.getParameters().isEmpty() ) { + parameterLessConstructor = constructor; + } + else { + accessibleConstructors.add( constructor ); + } + + if ( constructor.getModifiers().contains( Modifier.PUBLIC ) ) { + publicConstructors.add( constructor ); + } + } + + if ( defaultAnnotatedConstructor != null ) { + // If a default annotated constructor exists it will be used, it has highest precedence + return getConstructorAccessor( type, defaultAnnotatedConstructor ); + } + + if ( publicConstructors.size() == 1 ) { + // If there is a single public constructor then use that one + ExecutableElement publicConstructor = publicConstructors.get( 0 ); + if ( publicConstructor.getParameters().isEmpty() ) { + // The public parameterless constructor + return null; + } + + return getConstructorAccessor( type, publicConstructor ); + } + + if ( parameterLessConstructor != null ) { + // If there is a constructor without parameters use it + return null; + } + + if ( accessibleConstructors.isEmpty() ) { + return null; + } + + if ( accessibleConstructors.size() > 1 ) { + + ctx.getMessager().printMessage( + method.getExecutable(), + GENERAL_AMBIGUOUS_CONSTRUCTORS, + type, + constructors.stream() + .map( ExecutableElement::getParameters ) + .map( ps -> ps.stream() + .map( VariableElement::asType ) + .map( String::valueOf ) + .collect( Collectors.joining( ", ", type.getName() + "(", ")" ) ) + ) + .collect( Collectors.joining( ", " ) ) + ); + return new ConstructorAccessor( true, Collections.emptyList(), Collections.emptyMap() ); + } + else { + return getConstructorAccessor( type, accessibleConstructors.get( 0 ) ); + } + + } + + private ConstructorAccessor getConstructorAccessor(Type type, ExecutableElement constructor) { + List constructorParameters = ctx.getTypeFactory() + .getParameters( (DeclaredType) type.getTypeMirror(), constructor ); + + List constructorProperties = null; + for ( AnnotationMirror annotationMirror : constructor.getAnnotationMirrors() ) { + if ( annotationMirror.getAnnotationType() + .asElement() + .getSimpleName() + .contentEquals( "ConstructorProperties" ) ) { + for ( Entry entry : annotationMirror + .getElementValues() + .entrySet() ) { + if ( entry.getKey().getSimpleName().contentEquals( "value" ) ) { + constructorProperties = getArrayValues( entry.getValue() ); + break; } } + break; + } + } + + if ( constructorProperties == null ) { + Map constructorAccessors = new LinkedHashMap<>(); + List parameterBindings = new ArrayList<>( constructorParameters.size() ); + for ( Parameter constructorParameter : constructorParameters ) { + String parameterName = constructorParameter.getName(); + Element parameterElement = constructorParameter.getElement(); + Accessor constructorAccessor = createConstructorAccessor( + parameterElement, + constructorParameter.getType().getTypeMirror(), + parameterName + ); + constructorAccessors.put( + parameterName, + constructorAccessor + ); + parameterBindings.add( ParameterBinding.fromTypeAndName( + constructorParameter.getType(), + constructorAccessor.getSimpleName() + ) ); + } + + return new ConstructorAccessor( parameterBindings, constructorAccessors ); + } + else if ( constructorProperties.size() != constructorParameters.size() ) { + ctx.getMessager().printMessage( + method.getExecutable(), + GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS, + type ); + return new ConstructorAccessor( true, Collections.emptyList(), Collections.emptyMap() ); + } + else { + Map constructorAccessors = new LinkedHashMap<>(); + List parameterBindings = new ArrayList<>( constructorProperties.size() ); + for ( int i = 0; i < constructorProperties.size(); i++ ) { + String parameterName = constructorProperties.get( i ); + Parameter constructorParameter = constructorParameters.get( i ); + Element parameterElement = constructorParameter.getElement(); + Accessor constructorAccessor = createConstructorAccessor( + parameterElement, + constructorParameter.getType().getTypeMirror(), + parameterName + ); + constructorAccessors.put( + parameterName, + constructorAccessor + ); + parameterBindings.add( ParameterBinding.fromTypeAndName( + constructorParameter.getType(), + constructorAccessor.getSimpleName() + ) ); + } + + return new ConstructorAccessor( parameterBindings, constructorAccessors ); + } + } + + private Accessor createConstructorAccessor(Element element, TypeMirror accessedType, String parameterName) { + String safeParameterName = Strings.getSafeVariableName( + parameterName, + existingVariableNames + ); + existingVariableNames.add( safeParameterName ); + return new ElementAccessor( element, accessedType, safeParameterName ); + } + + private boolean hasDefaultAnnotationFromAnyPackage(Element element) { + for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { + if ( annotationMirror.getAnnotationType() + .asElement() + .getSimpleName() + .contentEquals( "Default" ) ) { + return true; + } + } + + return false; + } + + private List getArrayValues(AnnotationValue av) { + + if ( av.getValue() instanceof List ) { + List result = new ArrayList<>(); + for ( AnnotationValue v : getValueAsList( av ) ) { + Object value = v.getValue(); + if ( value instanceof String ) { + result.add( (String) value ); + } + else { + return null; + } + } + return result; + } + else { + return null; } } + @SuppressWarnings("unchecked") + private List getValueAsList(AnnotationValue av) { + return (List) av.getValue(); + } + + /** + * Determine whether defined mappings should be handled on the result type. + * They should be, if any of the following is true: + *
        + *
      • The {@code resultTypeToMap} is not abstract
      • + *
      • There is a factory method
      • + *
      • The method is an update method
      • + *
      + * Otherwise, it means that we have reached this because subclass mappings are being used + * and the chosen strategy is runtime exception. + * + * @param resultTypeToMap the type in which the defined target properties are defined + * @return {@code true} if defined mappings should be handled for the result type, {@code false} otherwise + */ + private boolean shouldHandledDefinedMappings(Type resultTypeToMap) { + if ( !resultTypeToMap.isAbstract() ) { + return true; + } + + if ( hasFactoryMethod ) { + return true; + } + + if ( method.isUpdateMethod() ) { + return true; + } + + return false; + } + /** * Iterates over all defined mapping methods ({@code @Mapping(s)}), either directly given or inherited from the * inverse mapping method. @@ -383,48 +1264,65 @@ public int compare(PropertyMapping o1, PropertyMapping o2) { *

      * It is furthermore checked whether the given mappings are correct. When an error occurs, the method continues * in search of more problems. + * + * @param resultTypeToMap the type in which the defined target properties are defined */ - private boolean handleDefinedMappings() { + private boolean handleDefinedMappings(Type resultTypeToMap) { boolean errorOccurred = false; - Set handledTargets = new HashSet(); + Set handledTargets = new HashSet<>(); // first we have to handle nested target mappings - if ( method.getMappingOptions().hasNestedTargetReferences() ) { - errorOccurred = handleDefinedNestedTargetMapping( handledTargets ); + if ( mappingReferences.hasNestedTargetReferences() ) { + errorOccurred = handleDefinedNestedTargetMapping( handledTargets, resultTypeToMap ); } - for ( Map.Entry> entry : methodMappings.entrySet() ) { - for ( Mapping mapping : entry.getValue() ) { - TargetReference targetReference = mapping.getTargetReference(); - if ( targetReference.isValid() ) { - if ( !handledTargets.contains( first( targetReference.getPropertyEntries() ).getFullName() ) ) { - if ( handleDefinedMapping( mapping, handledTargets ) ) { - errorOccurred = true; - } + for ( MappingReference mapping : mappingReferences.getMappingReferences() ) { + if ( mapping.isValid() ) { + String target = mapping.getTargetReference().getShallowestPropertyName(); + if ( target == null ) { + // When the shallowest property name is null then it is for @Mapping(target = ".") + if ( this.targetThisReferences == null ) { + this.targetThisReferences = new ArrayList<>(); } + this.targetThisReferences.add( mapping ); + continue; } - else { - errorOccurred = true; + if ( !handledTargets.contains( target ) ) { + if ( handleDefinedMapping( mapping, resultTypeToMap, handledTargets ) ) { + errorOccurred = true; + } + } + if ( mapping.getSourceReference() != null ) { + String source = mapping.getSourceReference().getShallowestPropertyName(); + if ( source != null ) { + unprocessedSourceProperties.remove( source ); + } } } + else { + errorOccurred = true; + } } + + // remove the remaining name based properties for ( String handledTarget : handledTargets ) { - // In order to avoid: "Unknown property foo in return type" in case of duplicate - // target mappings unprocessedTargetProperties.remove( handledTarget ); + unprocessedConstructorProperties.remove( handledTarget ); unprocessedDefinedTargets.remove( handledTarget ); - unprocessedSourceProperties.remove( handledTarget ); } return errorOccurred; } - private boolean handleDefinedNestedTargetMapping(Set handledTargets) { + private boolean handleDefinedNestedTargetMapping(Set handledTargets, Type resultTypeToMap) { NestedTargetPropertyMappingHolder holder = new NestedTargetPropertyMappingHolder.Builder() .mappingContext( ctx ) .method( method ) + .targetPropertiesWriteAccessors( unprocessedTargetProperties ) + .targetPropertyType( resultTypeToMap ) + .mappingReferences( mappingReferences ) .existingVariableNames( existingVariableNames ) .build(); @@ -432,24 +1330,24 @@ private boolean handleDefinedNestedTargetMapping(Set handledTargets) { propertyMappings.addAll( holder.getPropertyMappings() ); handledTargets.addAll( holder.getHandledTargets() ); // Store all the unprocessed defined targets. - for ( Entry> entry : holder.getUnprocessedDefinedTarget().entrySet() ) { + for ( Entry> entry : holder.getUnprocessedDefinedTarget() + .entrySet() ) { if ( entry.getValue().isEmpty() ) { continue; } - unprocessedDefinedTargets.put( entry.getKey().getName(), entry.getValue() ); + unprocessedDefinedTargets.put( entry.getKey(), entry.getValue() ); } return holder.hasErrorOccurred(); } - private boolean handleDefinedMapping(Mapping mapping, Set handledTargets) { - + private boolean handleDefinedMapping(MappingReference mappingRef, Type resultTypeToMap, + Set handledTargets) { boolean errorOccured = false; PropertyMapping propertyMapping = null; - TargetReference targetRef = mapping.getTargetReference(); - PropertyEntry targetProperty = first( targetRef.getPropertyEntries() ); - String propertyName = targetProperty.getName(); + TargetReference targetRef = mappingRef.getTargetReference(); + MappingOptions mapping = mappingRef.getMapping(); // unknown properties given via dependsOn()? for ( String dependency : mapping.getDependsOn() ) { @@ -465,80 +1363,301 @@ private boolean handleDefinedMapping(Mapping mapping, Set handledTargets } } - // check the mapping options - // its an ignored property mapping - if ( mapping.isIgnored() ) { - propertyMapping = null; - handledTargets.add( mapping.getTargetName() ); + String targetPropertyName = first( targetRef.getPropertyEntries() ); + + // check if source / expression / constant are not somehow handled already + if ( unprocessedDefinedTargets.containsKey( targetPropertyName ) ) { + return false; } - // its a plain-old property mapping - else if ( mapping.getSourceName() != null ) { + Accessor targetWriteAccessor = unprocessedTargetProperties.get( targetPropertyName ); + ReadAccessor targetReadAccessor = resultTypeToMap.getReadAccessor( + targetPropertyName, + method.getSourceParameters().size() == 1 + ); - // determine source parameter - SourceReference sourceRef = mapping.getSourceReference(); - if ( sourceRef.isValid() ) { + if ( targetWriteAccessor == null ) { + if ( targetReadAccessor == null ) { + MappingOptions.InheritContext inheritContext = mapping.getInheritContext(); + if ( inheritContext != null ) { + if ( inheritContext.isForwarded() && + inheritContext.getTemplateMethod().isUpdateMethod() != method.isUpdateMethod() ) { + // When a configuration is inherited and the template method is not same type as the current + // method then we can safely ignore this mapping. + // This means that a property which is inherited might be present for a direct mapping + // via the Builder, but not for an update mapping (directly on the object itself), + // or vice versa + return false; + } + else if ( inheritContext.isReversed() ) { + // When a configuration is reverse inherited and there are no read or write accessor + // then we should ignore this mapping. + // This most likely means that we were mapping the source parameter to the target. + // If the error is due to something else it will be reported on the original mapping + return false; + } + } + + Message msg; + String[] args; + + Set readAccessors = resultTypeToMap.getPropertyReadAccessors().keySet(); + String mostSimilarProperty = Strings.getMostSimilarWord( targetPropertyName, readAccessors ); + + Element elementForMessage = mapping.getElement(); + if ( elementForMessage == null ) { + elementForMessage = method.getExecutable(); + } + + if ( mapping.isIgnored() && mapping.getElement() == null ) { + msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_IGNORED; + args = new String[] { + targetPropertyName, + resultTypeToMap.describe(), + mostSimilarProperty + }; + } + else { + if ( targetRef.getPathProperties().isEmpty() ) { + msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE; + args = new String[] { + targetPropertyName, + resultTypeToMap.describe(), + mostSimilarProperty + }; + } + else { + List pathProperties = new ArrayList<>( targetRef.getPathProperties() ); + pathProperties.add( mostSimilarProperty ); + msg = Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_TYPE; + args = new String[] { + targetPropertyName, + resultTypeToMap.describe(), + mapping.getTargetName(), + Strings.join( pathProperties, "." ) + }; + } + } + + ctx.getMessager() + .printMessage( + elementForMessage, + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + msg, + args + ); + return true; + } + else if ( mapping.getInheritContext() != null && mapping.getInheritContext().isReversed() ) { + // read only reversed mappings are implicitly ignored + return false; + } + else if ( !mapping.isIgnored() ) { + // report an error for read only mappings + Message msg; + Object[] args; + + if ( Objects.equals( targetPropertyName, mapping.getTargetName() ) ) { + msg = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE; + args = new Object[] { + mapping.getTargetName(), + resultTypeToMap.describe() + }; + } + else { + msg = Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_TYPE; + args = new Object[] { + targetPropertyName, + resultTypeToMap.describe(), + mapping.getTargetName() + }; + } + ctx.getMessager() + .printMessage( + mapping.getElement(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + msg, + args + ); + return true; + } + } + + // check the mapping options + // its an ignored property mapping + if ( mapping.isIgnored() ) { + if ( targetWriteAccessor != null && targetWriteAccessor.getAccessorType() == AccessorType.PARAMETER ) { + // Even though the property is ignored this is a constructor parameter. + // Therefore we have to initialize it + Type accessedType = ctx.getTypeFactory() + .getType( targetWriteAccessor.getAccessedType() ); - // targetProperty == null can occur: we arrived here because we want as many errors - // as possible before we stop analysing - propertyMapping = new PropertyMappingBuilder() + propertyMapping = new JavaExpressionMappingBuilder() .mappingContext( ctx ) .sourceMethod( method ) - .targetProperty( targetProperty ) - .targetPropertyName( mapping.getTargetName() ) - .sourceReference( sourceRef ) - .selectionParameters( mapping.getSelectionParameters() ) - .formattingParameters( mapping.getFormattingParameters() ) + .javaExpression( accessedType.getNull() ) .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) .dependsOn( mapping.getDependsOn() ) - .defaultValue( mapping.getDefaultValue() ) - .defaultJavaExpression( mapping.getDefaultJavaExpression() ) + .mirror( mapping.getMirror() ) .build(); - handledTargets.add( propertyName ); - unprocessedSourceParameters.remove( sourceRef.getParameter() ); - } - else { - errorOccured = true; } + handledTargets.add( targetPropertyName ); } - // its a constant + // it's a constant // if we have an unprocessed target that means that it most probably is nested and we should // not generated any mapping for it now. Eventually it will be done though - else if ( mapping.getConstant() != null && !unprocessedDefinedTargets.containsKey( propertyName ) ) { + else if ( mapping.getConstant() != null ) { propertyMapping = new ConstantMappingBuilder() .mappingContext( ctx ) .sourceMethod( method ) .constantExpression( mapping.getConstant() ) - .targetProperty( targetProperty ) - .targetPropertyName( mapping.getTargetName() ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) .formattingParameters( mapping.getFormattingParameters() ) .selectionParameters( mapping.getSelectionParameters() ) + .options( mapping ) .existingVariableNames( existingVariableNames ) .dependsOn( mapping.getDependsOn() ) .mirror( mapping.getMirror() ) .build(); - handledTargets.add( mapping.getTargetName() ); + handledTargets.add( targetPropertyName ); } - // its an expression + // it's an expression // if we have an unprocessed target that means that it most probably is nested and we should // not generated any mapping for it now. Eventually it will be done though - else if ( mapping.getJavaExpression() != null && !unprocessedDefinedTargets.containsKey( propertyName ) ) { + else if ( mapping.getJavaExpression() != null ) { + + propertyMapping = new JavaExpressionMappingBuilder() + .mappingContext( ctx ) + .sourceMethod( method ) + .javaExpression( mapping.getJavaExpression() ) + .existingVariableNames( existingVariableNames ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .dependsOn( mapping.getDependsOn() ) + .mirror( mapping.getMirror() ) + .build(); + handledTargets.add( targetPropertyName ); + } + // it's a plain-old property mapping + else { + + SourceReference sourceRef = mappingRef.getSourceReference(); + // sourceRef is not defined, check if a source property has the same name + if ( sourceRef == null ) { + // Here we follow the same rules as when we implicitly map + // When we implicitly map we first do property name based mapping + // i.e. look for matching properties in the source types + // and then do parameter name based mapping + for ( Parameter sourceParameter : method.getSourceParameters() ) { + SourceReference matchingSourceRef = getSourceRefByTargetName( + sourceParameter, + targetPropertyName + ); + if ( matchingSourceRef != null ) { + if ( sourceRef != null ) { + errorOccured = true; + // This can only happen when the target property matches multiple properties + // within the different source parameters + ctx.getMessager() + .printMessage( + method.getExecutable(), + mappingRef.getMapping().getMirror(), + Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, + targetPropertyName + ); + break; + } + // We can't break here since it is possible that the same property exists in multiple + // source parameters + sourceRef = matchingSourceRef; + } + } + + } + + if ( sourceRef == null ) { + // still no match. Try if one of the parameters has the same name + sourceRef = method.getSourceParameters() + .stream() + .filter( p -> targetPropertyName.equals( p.getName() ) ) + .findAny() + .map( p -> new SourceReference.BuilderFromProperty() + .sourceParameter( p ) + .name( targetPropertyName ) + .build() ) + .orElse( null ); + } + + if ( sourceRef != null ) { + // sourceRef == null is not considered an error here + if ( sourceRef.isValid() ) { + Parameter sourceParameter = sourceRef.getParameter(); + + // targetProperty == null can occur: we arrived here because we want as many errors + // as possible before we stop analysing + propertyMapping = new PropertyMappingBuilder() + .mappingContext( ctx ) + .sourceMethod( method ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) + .sourcePropertyName( mapping.getSourceName() ) + .sourceReference( sourceRef.withParameter( + sourceParametersReassignments.get( sourceParameter.getName() ) ) ) + .selectionParameters( mapping.getSelectionParameters() ) + .formattingParameters( mapping.getFormattingParameters() ) + .existingVariableNames( existingVariableNames ) + .dependsOn( mapping.getDependsOn() ) + .defaultValue( mapping.getDefaultValue() ) + .defaultJavaExpression( mapping.getDefaultJavaExpression() ) + .conditionJavaExpression( mapping.getConditionJavaExpression() ) + .mirror( mapping.getMirror() ) + .options( mapping ) + .build(); + handledTargets.add( targetPropertyName ); + unprocessedSourceParameters.remove( sourceParameter ); + // If the source parameter was directly mapped + if ( sourceRef.getPropertyEntries().isEmpty() ) { + // Ignore all of its source properties completely + ignoreSourceProperties( sourceParameter ); + } + else { + unprocessedSourceProperties.remove( sourceRef.getShallowestPropertyName() ); + } + } + else { + errorOccured = true; + } + } + else { + errorOccured = true; - propertyMapping = new JavaExpressionMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .javaExpression( mapping.getJavaExpression() ) - .existingVariableNames( existingVariableNames ) - .targetProperty( targetProperty ) - .targetPropertyName( mapping.getTargetName() ) - .dependsOn( mapping.getDependsOn() ) - .build(); - handledTargets.add( mapping.getTargetName() ); + if ( method.getSourceParameters().size() == 1 ) { + ctx.getMessager() + .printMessage( + method.getExecutable(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET, + method.getSourceParameters().get( 0 ).getName(), + targetPropertyName + ); + } + else { + ctx.getMessager() + .printMessage( + method.getExecutable(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET, + targetPropertyName + ); + } + } } - // remaining are the mappings without a 'source' so, 'only' a date format or qualifiers if ( propertyMapping != null ) { propertyMappings.add( propertyMapping ); @@ -547,6 +1666,41 @@ else if ( mapping.getJavaExpression() != null && !unprocessedDefinedTargets.cont return errorOccured; } + /** + * When target this mapping present, iterates over unprocessed targets. + *

      + * When a target property matches its name with the (nested) source property, it is added to the list if and + * only if it is an unprocessed target property. + *

      + * duplicates will be handled by {@link #applyPropertyNameBasedMapping(List)} + */ + private void applyTargetThisMapping() { + if ( this.targetThisReferences == null ) { + return; + } + Set handledTargetProperties = new HashSet<>(); + for ( MappingReference targetThis : this.targetThisReferences ) { + + // handle all prior unprocessed target properties, but let duplicates fall through + List sourceRefs = targetThis + .getSourceReference() + .push( ctx.getTypeFactory(), ctx.getMessager(), method ) + .stream() + .filter( sr -> unprocessedTargetProperties.containsKey( sr.getDeepestPropertyName() ) + || handledTargetProperties.contains( sr.getDeepestPropertyName() ) ) + .collect( Collectors.toList() ); + + // apply name based mapping + applyPropertyNameBasedMapping( sourceRefs ); + + // add handled target properties + handledTargetProperties.addAll( sourceRefs.stream() + .map( SourceReference::getDeepestPropertyName ) + .collect( + Collectors.toList() ) ); + } + } + /** * Iterates over all target properties and all source parameters. *

      @@ -554,87 +1708,62 @@ else if ( mapping.getJavaExpression() != null && !unprocessedDefinedTargets.cont * the set of remaining target properties. */ private void applyPropertyNameBasedMapping() { + List sourceReferences = new ArrayList<>(); + for ( String targetPropertyName : unprocessedTargetProperties.keySet() ) { + for ( Parameter sourceParameter : method.getSourceParameters() ) { + SourceReference sourceRef = getSourceRefByTargetName( sourceParameter, targetPropertyName ); + if ( sourceRef != null ) { + sourceReferences.add( sourceRef ); + } + } + } + applyPropertyNameBasedMapping( sourceReferences ); + } - Iterator> targetPropertyEntriesIterator = - unprocessedTargetProperties.entrySet().iterator(); - - while ( targetPropertyEntriesIterator.hasNext() ) { - - Entry targetProperty = targetPropertyEntriesIterator.next(); - String targetPropertyName = targetProperty.getKey(); - - PropertyMapping propertyMapping = null; - - if ( propertyMapping == null ) { - - for ( Parameter sourceParameter : method.getSourceParameters() ) { - - Type sourceType = sourceParameter.getType(); - - if ( sourceType.isPrimitive() ) { - continue; - } + /** + * Iterates over all target properties and all source parameters. + *

      + * When a property name match occurs, the remainder will be checked for duplicates. Matches will be removed from + * the set of remaining target properties. + */ + private void applyPropertyNameBasedMapping(List sourceReferences) { + + for ( SourceReference sourceRef : sourceReferences ) { + + String targetPropertyName = sourceRef.getDeepestPropertyName(); + Accessor targetPropertyWriteAccessor = unprocessedTargetProperties.remove( targetPropertyName ); + unprocessedConstructorProperties.remove( targetPropertyName ); + if ( targetPropertyWriteAccessor == null ) { + // TODO improve error message + ctx.getMessager() + .printMessage( method.getExecutable(), + Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, + targetPropertyName + ); + continue; + } - PropertyMapping newPropertyMapping = null; - - Accessor sourceReadAccessor = - sourceParameter.getType().getPropertyReadAccessors().get( targetPropertyName ); - - ExecutableElementAccessor sourcePresenceChecker = - sourceParameter.getType().getPropertyPresenceCheckers().get( targetPropertyName ); - - if ( sourceReadAccessor != null ) { - Mapping mapping = singleMapping.getSingleMappingByTargetPropertyName( - targetProperty.getKey() ); - DeclaredType declaredSourceType = (DeclaredType) sourceParameter.getType().getTypeMirror(); - - SourceReference sourceRef = new SourceReference.BuilderFromProperty() - .sourceParameter( sourceParameter ) - .type( ctx.getTypeFactory().getReturnType( declaredSourceType, sourceReadAccessor ) ) - .readAccessor( sourceReadAccessor ) - .presenceChecker( sourcePresenceChecker ) - .name( targetProperty.getKey() ) - .build(); - - newPropertyMapping = new PropertyMappingBuilder() - .mappingContext( ctx ) - .sourceMethod( method ) - .targetWriteAccessor( targetProperty.getValue() ) - .targetReadAccessor( getTargetPropertyReadAccessor( targetPropertyName ) ) - .targetPropertyName( targetPropertyName ) - .sourceReference( sourceRef ) - .formattingParameters( mapping != null ? mapping.getFormattingParameters() : null ) - .selectionParameters( mapping != null ? mapping.getSelectionParameters() : null ) - .defaultValue( mapping != null ? mapping.getDefaultValue() : null ) - .existingVariableNames( existingVariableNames ) - .dependsOn( mapping != null ? mapping.getDependsOn() : Collections.emptyList() ) - .forgeMethodWithMappingOptions( extractAdditionalOptions( targetPropertyName, false ) ) - .build(); - - unprocessedSourceParameters.remove( sourceParameter ); - } + ReadAccessor targetPropertyReadAccessor = + method.getResultType() + .getReadAccessor( targetPropertyName, method.getSourceParameters().size() == 1 ); + MappingReferences mappingRefs = extractMappingReferences( targetPropertyName, false ); + PropertyMapping propertyMapping = new PropertyMappingBuilder().mappingContext( ctx ) + .sourceMethod( method ) + .sourcePropertyName( targetPropertyName ) + .target( targetPropertyName, targetPropertyReadAccessor, targetPropertyWriteAccessor ) + .sourceReference( sourceRef ) + .existingVariableNames( existingVariableNames ) + .forgeMethodWithMappingReferences( mappingRefs ) + .options( method.getOptions().getBeanMapping() ) + .build(); - if ( propertyMapping != null && newPropertyMapping != null ) { - // TODO improve error message - ctx.getMessager().printMessage( - method.getExecutable(), - Message.BEANMAPPING_SEVERAL_POSSIBLE_SOURCES, - targetPropertyName - ); - break; - } - else if ( newPropertyMapping != null ) { - propertyMapping = newPropertyMapping; - } - } - } + unprocessedSourceParameters.remove( sourceRef.getParameter() ); if ( propertyMapping != null ) { propertyMappings.add( propertyMapping ); - targetPropertyEntriesIterator.remove(); - unprocessedDefinedTargets.remove( targetPropertyName ); - unprocessedSourceProperties.remove( targetPropertyName ); } + unprocessedDefinedTargets.remove( targetPropertyName ); + unprocessedSourceProperties.remove( targetPropertyName ); } } @@ -653,25 +1782,24 @@ private void applyParameterNameBasedMapping() { Parameter sourceParameter = sourceParameters.next(); if ( sourceParameter.getName().equals( targetProperty.getKey() ) ) { - Mapping mapping = singleMapping.getSingleMappingByTargetPropertyName( targetProperty.getKey() ); SourceReference sourceRef = new SourceReference.BuilderFromProperty() .sourceParameter( sourceParameter ) .name( targetProperty.getKey() ) .build(); + ReadAccessor targetPropertyReadAccessor = + method.getResultType() + .getReadAccessor( targetProperty.getKey(), method.getSourceParameters().size() == 1 ); + MappingReferences mappingRefs = extractMappingReferences( targetProperty.getKey(), false ); PropertyMapping propertyMapping = new PropertyMappingBuilder() .mappingContext( ctx ) .sourceMethod( method ) - .targetWriteAccessor( targetProperty.getValue() ) - .targetReadAccessor( getTargetPropertyReadAccessor( targetProperty.getKey() ) ) - .targetPropertyName( targetProperty.getKey() ) + .target( targetProperty.getKey(), targetPropertyReadAccessor, targetProperty.getValue() ) .sourceReference( sourceRef ) - .formattingParameters( mapping != null ? mapping.getFormattingParameters() : null ) - .selectionParameters( mapping != null ? mapping.getSelectionParameters() : null ) .existingVariableNames( existingVariableNames ) - .dependsOn( mapping != null ? mapping.getDependsOn() : Collections.emptyList() ) - .forgeMethodWithMappingOptions( extractAdditionalOptions( targetProperty.getKey(), false ) ) + .forgeMethodWithMappingReferences( mappingRefs ) + .options( method.getOptions().getBeanMapping() ) .build(); propertyMappings.add( propertyMapping ); @@ -679,203 +1807,480 @@ private void applyParameterNameBasedMapping() { sourceParameters.remove(); unprocessedDefinedTargets.remove( targetProperty.getKey() ); unprocessedSourceProperties.remove( targetProperty.getKey() ); + unprocessedConstructorProperties.remove( targetProperty.getKey() ); + ignoreSourceProperties( sourceParameter ); } } } } - private MappingOptions extractAdditionalOptions(String targetProperty, boolean restrictToDefinedMappings) { - MappingOptions additionalOptions = null; - if ( unprocessedDefinedTargets.containsKey( targetProperty ) ) { - - Map> mappings = new HashMap>(); - for ( Mapping mapping : unprocessedDefinedTargets.get( targetProperty ) ) { - mappings.put( mapping.getTargetName(), Collections.singletonList( mapping ) ); + private void ignoreSourceProperties(Parameter sourceParameter) { + // The source parameter was directly mapped so ignore all of its source properties completely + if ( !sourceParameter.getType().isPrimitive() && !sourceParameter.getType().isArrayType() ) { + // We explicitly ignore source properties from primitives or array types + Map readAccessors = sourceParameter.getType() + .getPropertyReadAccessors(); + for ( String sourceProperty : readAccessors.keySet() ) { + unprocessedSourceProperties.remove( sourceProperty ); } - additionalOptions = MappingOptions.forMappingsOnly( mappings, restrictToDefinedMappings ); } - return additionalOptions; } - private Accessor getTargetPropertyReadAccessor(String propertyName) { - return method.getResultType().getPropertyReadAccessors().get( propertyName ); - } + private SourceReference getSourceRefByTargetName(Parameter sourceParameter, String targetPropertyName) { + + SourceReference sourceRef = null; + + Type sourceParameterType = sourceParameter.getType(); + Parameter sourceParameterToUse = sourceParameter; + if ( sourceParameterType.isOptionalType() ) { + sourceParameterType = sourceParameterType.getOptionalBaseType(); + sourceParameterToUse = sourceParametersReassignments.get( sourceParameter.getName() ); + } + if ( sourceParameterType.isPrimitive() || sourceParameterType.isArrayType() ) { + return sourceRef; + } - private ReportingPolicyPrism getUnmappedTargetPolicy() { - MappingOptions mappingOptions = method.getMappingOptions(); - if ( mappingOptions.getBeanMapping() != null && - mappingOptions.getBeanMapping().getReportingPolicy() != null ) { - return mappingOptions.getBeanMapping().getReportingPolicy(); + ReadAccessor sourceReadAccessor = sourceParameterType + .getReadAccessor( targetPropertyName, method.getSourceParameters().size() == 1 ); + if ( sourceReadAccessor != null ) { + // property mapping + PresenceCheckAccessor sourcePresenceChecker = + sourceParameterType.getPresenceChecker( targetPropertyName ); + + DeclaredType declaredSourceType = (DeclaredType) sourceParameterType.getTypeMirror(); + Type returnType = ctx.getTypeFactory().getReturnType( declaredSourceType, sourceReadAccessor ); + sourceRef = new SourceReference.BuilderFromProperty().sourceParameter( sourceParameterToUse ) + .type( returnType ) + .readAccessor( sourceReadAccessor ) + .presenceChecker( sourcePresenceChecker ) + .name( targetPropertyName ) + .build(); } + return sourceRef; + } - MapperConfiguration mapperSettings = MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ); + private MappingReferences extractMappingReferences(String targetProperty, boolean restrictToDefinedMappings) { + if ( unprocessedDefinedTargets.containsKey( targetProperty ) ) { + Set mappings = unprocessedDefinedTargets.get( targetProperty ); + return new MappingReferences( mappings, restrictToDefinedMappings ); + } + return null; + } - return mapperSettings.unmappedTargetPolicy( ctx.getOptions() ); + private ReportingPolicyGem getUnmappedTargetPolicy() { + if ( mappingReferences.isForForgedMethods() ) { + return ReportingPolicyGem.IGNORE; + } + // If we have ignoreByDefault = true, unprocessed target properties are not an issue. + if ( method.getOptions().getBeanMapping().isIgnoredByDefault() ) { + return ReportingPolicyGem.IGNORE; + } + if ( method.getOptions().getBeanMapping() != null ) { + return method.getOptions().getBeanMapping().unmappedTargetPolicy(); + } + return method.getOptions().getMapper().unmappedTargetPolicy(); } - private void reportErrorForUnmappedTargetPropertiesIfRequired() { + private void reportErrorForUnmappedTargetPropertiesIfRequired(Type resultType, + boolean constructorAccessorHadError) { // fetch settings from element to implement - ReportingPolicyPrism unmappedTargetPolicy = getUnmappedTargetPolicy(); + ReportingPolicyGem unmappedTargetPolicy = getUnmappedTargetPolicy(); - if ( method instanceof ForgedMethod && targetProperties.isEmpty() ) { - //TODO until we solve 1140 we report this error when the target properties are empty - ForgedMethod forgedMethod = (ForgedMethod) method; - if ( forgedMethod.getHistory() == null ) { - Type sourceType = this.method.getParameters().get( 0 ).getType(); - Type targetType = this.method.getReturnType(); - ctx.getMessager().printMessage( - this.method.getExecutable(), - Message.PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND, - sourceType, - targetType, - targetType, - sourceType - ); + if ( targetProperties.isEmpty() ) { + if ( method instanceof ForgedMethod ) { + ForgedMethod forgedMethod = (ForgedMethod) method; + if ( forgedMethod.getHistory() == null ) { + Type sourceType = this.method.getParameters().get( 0 ).getType(); + Type targetType = this.method.getReturnType(); + ctx.getMessager().printMessage( + this.method.getExecutable(), + Message.PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND, + sourceType.describe(), + targetType.describe(), + targetType.describe(), + sourceType.describe() + ); + } + else { + ForgedMethodHistory history = forgedMethod.getHistory(); + ctx.getMessager().printMessage( + this.method.getExecutable(), + Message.PROPERTYMAPPING_FORGED_MAPPING_WITH_HISTORY_NOT_FOUND, + history.createSourcePropertyErrorMessage(), + history.getTargetType().describe(), + history.createTargetPropertyName(), + history.getTargetType().describe(), + history.getSourceType().describe() + ); + } } - else { - ForgedMethodHistory history = forgedMethod.getHistory(); + else if ( !constructorAccessorHadError ) { ctx.getMessager().printMessage( - this.method.getExecutable(), - Message.PROPERTYMAPPING_MAPPING_NOT_FOUND, - history.createSourcePropertyErrorMessage(), - history.getTargetType(), - history.createTargetPropertyName(), - history.getTargetType(), - history.getSourceType() + method.getExecutable(), + Message.PROPERTYMAPPING_TARGET_HAS_NO_TARGET_PROPERTIES, + resultType.describe() ); } } else if ( !unprocessedTargetProperties.isEmpty() && unmappedTargetPolicy.requiresReport() ) { - Message msg = unmappedTargetPolicy.getDiagnosticKind() == Diagnostic.Kind.ERROR ? - Message.BEANMAPPING_UNMAPPED_TARGETS_ERROR : Message.BEANMAPPING_UNMAPPED_TARGETS_WARNING; + Message unmappedPropertiesMsg; + Message unmappedForgedPropertiesMsg; + if ( unmappedTargetPolicy.getDiagnosticKind() == Diagnostic.Kind.ERROR ) { + unmappedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_TARGETS_ERROR; + unmappedForgedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_FORGED_TARGETS_ERROR; + } + else { + unmappedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_TARGETS_WARNING; + unmappedForgedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_FORGED_TARGETS_WARNING; + } + + reportErrorForUnmappedProperties( + unprocessedTargetProperties, + unmappedPropertiesMsg, + unmappedForgedPropertiesMsg + ); + + } + } + + private ReportingPolicyGem getUnmappedSourcePolicy() { + if ( mappingReferences.isForForgedMethods() ) { + return ReportingPolicyGem.IGNORE; + } + return method.getOptions().getBeanMapping().unmappedSourcePolicy(); + } + + private void reportErrorForUnmappedSourcePropertiesIfRequired() { + ReportingPolicyGem unmappedSourcePolicy = getUnmappedSourcePolicy(); + if ( !unprocessedSourceProperties.isEmpty() && unmappedSourcePolicy.requiresReport() ) { + Message unmappedPropertiesMsg; + Message unmappedForgedPropertiesMsg; + if ( unmappedSourcePolicy.getDiagnosticKind() == Diagnostic.Kind.ERROR ) { + unmappedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_SOURCES_ERROR; + unmappedForgedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_FORGED_SOURCES_ERROR; + } + else { + unmappedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_SOURCES_WARNING; + unmappedForgedPropertiesMsg = Message.BEANMAPPING_UNMAPPED_FORGED_SOURCES_WARNING; + } + + reportErrorForUnmappedProperties( + unprocessedSourceProperties, + unmappedPropertiesMsg, + unmappedForgedPropertiesMsg ); + } + } + + private void reportErrorForUnmappedProperties(Map unmappedProperties, + Message unmappedPropertiesMsg, + Message unmappedForgedPropertiesMsg) { + if ( !( method instanceof ForgedMethod ) ) { Object[] args = new Object[] { MessageFormat.format( "{0,choice,1#property|1 typeParameters = parameterType.getTypeParameters(); + if ( typeParameters.size() != 2 || !typeParameters.get( 0 ).isString() ) { + Message message = typeParameters.isEmpty() ? + Message.MAPTOBEANMAPPING_RAW_MAP : + Message.MAPTOBEANMAPPING_WRONG_KEY_TYPE; + ctx.getMessager() + .printMessage( + method.getExecutable(), + message, + sourceParameter.getName(), + String.format( + "Map<%s,%s>", + !typeParameters.isEmpty() ? typeParameters.get( 0 ).describe() : "", + typeParameters.size() > 1 ? typeParameters.get( 1 ).describe() : "" + ) + ); + } + } + } + } + } + + private static class ConstructorAccessor { + private final boolean hasError; + private final List parameterBindings; + private final Map constructorAccessors; + + private ConstructorAccessor( + List parameterBindings, + Map constructorAccessors) { + this( false, parameterBindings, constructorAccessors ); + } + + private ConstructorAccessor(boolean hasError, List parameterBindings, + Map constructorAccessors) { + this.hasError = hasError; + this.parameterBindings = parameterBindings; + this.constructorAccessors = constructorAccessors; + } } + //CHECKSTYLE:OFF private BeanMappingMethod(Method method, + List annotations, Collection existingVariableNames, List propertyMappings, MethodReference factoryMethod, boolean mapNullToDefault, - Type resultType, + Type returnTypeToConstruct, + BuilderType returnTypeBuilder, List beforeMappingReferences, List afterMappingReferences, - MethodReference finalizerMethod) { + List beforeMappingReferencesWithFinalizedReturnType, + List afterMappingReferencesWithFinalizedReturnType, + List afterMappingReferencesWithOptionalReturnType, + MethodReference finalizerMethod, + MappingReferences mappingReferences, + List subclassMappings, + Map presenceChecksByParameter, + Type subclassExhaustiveException, + Map sourceParametersReassignments + ) { super( method, + annotations, existingVariableNames, factoryMethod, mapNullToDefault, beforeMappingReferences, afterMappingReferences ); + //CHECKSTYLE:ON this.propertyMappings = propertyMappings; + this.returnTypeBuilder = returnTypeBuilder; this.finalizerMethod = finalizerMethod; + this.subclassExhaustiveException = subclassExhaustiveException; + if ( this.finalizerMethod != null ) { + this.finalizedResultName = + Strings.getSafeVariableName( getResultName() + "Result", existingVariableNames ); + existingVariableNames.add( this.finalizedResultName ); + this.optionalResultName = + Strings.getSafeVariableName( getResultName() + "ResultOptional", existingVariableNames ); + existingVariableNames.add( this.optionalResultName ); + } + else { + this.finalizedResultName = null; + this.optionalResultName = + Strings.getSafeVariableName( getResultName() + "Optional", existingVariableNames ); + existingVariableNames.add( this.optionalResultName ); + } + this.mappingReferences = mappingReferences; - // intialize constant mappings as all mappings, but take out the ones that can be contributed to a + this.beforeMappingReferencesWithFinalizedReturnType = beforeMappingReferencesWithFinalizedReturnType; + this.afterMappingReferencesWithFinalizedReturnType = afterMappingReferencesWithFinalizedReturnType; + this.afterMappingReferencesWithOptionalReturnType = afterMappingReferencesWithOptionalReturnType; + + // initialize constant mappings as all mappings, but take out the ones that can be contributed to a // parameter mapping. - this.mappingsByParameter = new HashMap>(); - this.constantMappings = new ArrayList( propertyMappings ); + this.mappingsByParameter = new HashMap<>(); + this.constantMappings = new ArrayList<>( propertyMappings.size() ); + this.presenceChecksByParameter = presenceChecksByParameter; + this.constructorMappingsByParameter = new LinkedHashMap<>(); + this.constructorConstantMappings = new ArrayList<>(); + Set sourceParameterNames = new HashSet<>(); for ( Parameter sourceParameter : getSourceParameters() ) { - ArrayList mappingsOfParameter = new ArrayList(); - mappingsByParameter.put( sourceParameter.getName(), mappingsOfParameter ); - for ( PropertyMapping mapping : propertyMappings ) { - if ( sourceParameter.getName().equals( mapping.getSourceBeanName() ) ) { - mappingsOfParameter.add( mapping ); - constantMappings.remove( mapping ); + sourceParameterNames.add( sourceParameter.getName() ); + } + for ( PropertyMapping mapping : propertyMappings ) { + if ( mapping.isConstructorMapping() ) { + if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { + constructorMappingsByParameter.computeIfAbsent( + mapping.getSourceBeanName(), + key -> new ArrayList<>() + ).add( mapping ); } + else { + constructorConstantMappings.add( mapping ); + } + } + else if ( sourceParameterNames.contains( mapping.getSourceBeanName() ) ) { + mappingsByParameter.computeIfAbsent( mapping.getSourceBeanName(), key -> new ArrayList<>() ) + .add( mapping ); + } + else { + constantMappings.add( mapping ); } } - this.resultType = resultType; + this.returnTypeToConstruct = returnTypeToConstruct; + this.newInstance = ( returnTypeToConstruct != null && getFactoryMethod() == null ) + ? NewInstanceCreation.forType( returnTypeToConstruct ) + : null; + this.subclassMappings = subclassMappings; + this.sourceParametersReassignments = sourceParametersReassignments; } - public List getPropertyMappings() { - return propertyMappings; + public Type getSubclassExhaustiveException() { + return subclassExhaustiveException; } public List getConstantMappings() { return constantMappings; } + public List getConstructorConstantMappings() { + return constructorConstantMappings; + } + + public List getSubclassMappings() { + return subclassMappings; + } + + public String getFinalizedResultName() { + return finalizedResultName; + } + + public Type getFinalizedReturnType() { + Type returnType = getReturnType(); + if ( returnType.isOptionalType() ) { + return returnType.getOptionalBaseType(); + } + return returnType; + } + + public String getOptionalResultName() { + return optionalResultName; + } + + public List getBeforeMappingReferencesWithFinalizedReturnType() { + return beforeMappingReferencesWithFinalizedReturnType; + } + + public List getAfterMappingReferencesWithFinalizedReturnType() { + return afterMappingReferencesWithFinalizedReturnType; + } + + public List getAfterMappingReferencesWithOptionalReturnType() { + return afterMappingReferencesWithOptionalReturnType; + } + public List propertyMappingsByParameter(Parameter parameter) { // issues: #909 and #1244. FreeMarker has problem getting values from a map when the search key is size or value - return mappingsByParameter.get( parameter.getName() ); + return mappingsByParameter.getOrDefault( parameter.getName(), Collections.emptyList() ); } - @Override - public Type getResultType() { - if ( resultType == null ) { - return super.getResultType(); - } - else { - return resultType; - } + public List constructorPropertyMappingsByParameter(Parameter parameter) { + // issues: #909 and #1244. FreeMarker has problem getting values from a map when the search key is size or value + return constructorMappingsByParameter.getOrDefault( parameter.getName(), Collections.emptyList() ); + } + + public Type getReturnTypeToConstruct() { + return returnTypeToConstruct; + } + + public NewInstanceCreation getNewInstance() { + return newInstance; + } + + public boolean hasSubclassMappings() { + return !subclassMappings.isEmpty(); + } + + public boolean isAbstractReturnType() { + return getFactoryMethod() == null && returnTypeToConstruct != null + && returnTypeToConstruct.isAbstract(); + } + + public boolean hasConstructorMappings() { + return !constructorMappingsByParameter.isEmpty() || !constructorConstantMappings.isEmpty(); } public MethodReference getFinalizerMethod() { @@ -888,35 +2293,90 @@ public Set getImportTypes() { for ( PropertyMapping propertyMapping : propertyMappings ) { types.addAll( propertyMapping.getImportTypes() ); + if ( propertyMapping.isConstructorMapping() ) { + // We need to add the target type imports for a constructor mapper since we define its parameters + types.addAll( propertyMapping.getTargetType().getImportTypes() ); + } + } + for ( SubclassMapping subclassMapping : subclassMappings ) { + types.addAll( subclassMapping.getImportTypes() ); } - if ( !isExistingInstanceMapping() ) { - types.addAll( getResultType().getEffectiveType().getImportTypes() ); + if ( returnTypeToConstruct != null ) { + types.addAll( newInstance != null ? newInstance.getImportTypes() : returnTypeToConstruct.getImportTypes() ); + } + if ( returnTypeBuilder != null ) { + types.add( returnTypeBuilder.getOwningType() ); + } + for ( LifecycleCallbackMethodReference reference : beforeMappingReferencesWithFinalizedReturnType ) { + types.addAll( reference.getImportTypes() ); + } + for ( LifecycleCallbackMethodReference reference : afterMappingReferencesWithFinalizedReturnType ) { + types.addAll( reference.getImportTypes() ); } + for ( LifecycleCallbackMethodReference reference : afterMappingReferencesWithOptionalReturnType ) { + types.addAll( reference.getImportTypes() ); + } return types; } - public List getSourceParametersExcludingPrimitives() { - List sourceParameters = new ArrayList(); - for ( Parameter sourceParam : getSourceParameters() ) { - if ( !sourceParam.getType().isPrimitive() ) { - sourceParameters.add( sourceParam ); - } + public Collection getSourcePresenceChecks() { + return presenceChecksByParameter.values(); + } + + public Map getPresenceChecksByParameter() { + return presenceChecksByParameter; + } + + public PresenceCheck getPresenceCheckByParameter(Parameter parameter) { + return presenceChecksByParameter.get( parameter.getName() ); + } + + public List getSourceParametersNeedingPresenceCheck() { + return getSourceParameters().stream() + .filter( this::needsPresenceCheck ) + .collect( Collectors.toList() ); + } + + public List getSourceParametersNotNeedingPresenceCheck() { + return getSourceParameters().stream() + .filter( parameter -> !needsPresenceCheck( parameter ) ) + .collect( Collectors.toList() ); + } + + public Parameter getSourceParameterReassignment(Parameter parameter) { + return sourceParametersReassignments.get( parameter.getName() ); + } + + private boolean needsPresenceCheck(Parameter parameter) { + if ( !presenceChecksByParameter.containsKey( parameter.getName() ) ) { + return false; + } + + List mappings = propertyMappingsByParameter( parameter ); + if ( mappings.size() == 1 && doesNotNeedPresenceCheckForSourceParameter( mappings.get( 0 ) ) ) { + return false; } - return sourceParameters; + mappings = constructorPropertyMappingsByParameter( parameter ); + + if ( mappings.size() == 1 && doesNotNeedPresenceCheckForSourceParameter( mappings.get( 0 ) ) ) { + return false; + } + + return true; } - public List getSourcePrimitiveParameters() { - List sourceParameters = new ArrayList(); - for ( Parameter sourceParam : getSourceParameters() ) { - if ( sourceParam.getType().isPrimitive() ) { - sourceParameters.add( sourceParam ); - } + private boolean doesNotNeedPresenceCheckForSourceParameter(PropertyMapping mapping) { + if ( mapping.getAssignment().isCallingUpdateMethod() ) { + // If the mapping assignment is calling an update method then we should do a null check + // in the bean mapping + return false; } - return sourceParameters; + + return mapping.getAssignment().isSourceReferenceParameter(); } @Override @@ -940,36 +2400,16 @@ public boolean equals(Object obj) { if ( !super.equals( obj ) ) { return false; } - return propertyMappings != null ? propertyMappings.equals( that.propertyMappings ) : - that.propertyMappings == null; - } - private interface SingleMappingByTargetPropertyNameFunction { - - Mapping getSingleMappingByTargetPropertyName(String targetPropertyName); - } - - private static class EmptySingleMapping implements SingleMappingByTargetPropertyNameFunction { - - @Override - public Mapping getSingleMappingByTargetPropertyName(String targetPropertyName) { - return null; + if ( !Objects.equals( propertyMappings, that.propertyMappings ) ) { + return false; } - } - private static class SourceMethodSingleMapping implements SingleMappingByTargetPropertyNameFunction { - - private final SourceMethod sourceMethod; - - private SourceMethodSingleMapping(SourceMethod sourceMethod) { - this.sourceMethod = sourceMethod; + if ( !Objects.equals( mappingReferences, that.mappingReferences ) ) { + return false; } - @Override - public Mapping getSingleMappingByTargetPropertyName(String targetPropertyName) { - return sourceMethod.getSingleMappingByTargetPropertyName( targetPropertyName ); - } - } + return true; + } } - diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BuilderFinisherMethodResolver.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BuilderFinisherMethodResolver.java index 0948c7d112..848e2cc35f 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BuilderFinisherMethodResolver.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BuilderFinisherMethodResolver.java @@ -1,43 +1,45 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.Collection; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.VariableElement; +import org.mapstruct.ap.internal.gem.BuilderGem; import org.mapstruct.ap.internal.model.common.BuilderType; -import org.mapstruct.ap.internal.model.source.BeanMapping; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.prism.BuilderPrism; -import org.mapstruct.ap.internal.util.MapperConfiguration; +import org.mapstruct.ap.internal.util.Extractor; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; import static org.mapstruct.ap.internal.util.Collections.first; /** + * Factory for creating the appropriate builder finisher method. + * * @author Filip Hrisafov */ public class BuilderFinisherMethodResolver { private static final String DEFAULT_BUILD_METHOD_NAME = "build"; + private static final Extractor EXECUTABLE_ELEMENT_NAME_EXTRACTOR = + executableElement -> { + StringBuilder sb = new StringBuilder( executableElement.getSimpleName() ); + + sb.append( '(' ); + for ( VariableElement parameter : executableElement.getParameters() ) { + sb.append( parameter ); + } + + sb.append( ')' ); + return sb.toString(); + }; + private BuilderFinisherMethodResolver() { } @@ -49,14 +51,14 @@ public static MethodReference getBuilderFinisherMethod(Method method, BuilderTyp return null; } - BuilderPrism builderMapping = builderMappingPrism( method, ctx ); - if ( builderMapping == null && buildMethods.size() == 1 ) { + BuilderGem builder = method.getOptions().getBeanMapping().getBuilder(); + if ( builder == null && buildMethods.size() == 1 ) { return MethodReference.forMethodCall( first( buildMethods ).getSimpleName().toString() ); } else { String buildMethodPattern = DEFAULT_BUILD_METHOD_NAME; - if ( builderMapping != null ) { - buildMethodPattern = builderMapping.buildMethod(); + if ( builder != null ) { + buildMethodPattern = builder.buildMethod().get(); } for ( ExecutableElement buildMethod : buildMethods ) { String methodName = buildMethod.getSimpleName().toString(); @@ -65,25 +67,25 @@ public static MethodReference getBuilderFinisherMethod(Method method, BuilderTyp } } - if ( builderMapping == null ) { + if ( builder == null ) { ctx.getMessager().printMessage( method.getExecutable(), Message.BUILDER_NO_BUILD_METHOD_FOUND_DEFAULT, buildMethodPattern, builderType.getBuilder(), builderType.getBuildingType(), - Strings.join( buildMethods, ", " ) + Strings.join( buildMethods, ", ", EXECUTABLE_ELEMENT_NAME_EXTRACTOR ) ); } else { ctx.getMessager().printMessage( method.getExecutable(), - builderMapping.mirror, + builder.mirror(), Message.BUILDER_NO_BUILD_METHOD_FOUND, buildMethodPattern, builderType.getBuilder(), builderType.getBuildingType(), - Strings.join( buildMethods, ", " ) + Strings.join( buildMethods, ", ", EXECUTABLE_ELEMENT_NAME_EXTRACTOR ) ); } } @@ -91,11 +93,4 @@ public static MethodReference getBuilderFinisherMethod(Method method, BuilderTyp return null; } - private static BuilderPrism builderMappingPrism(Method method, MappingBuilderContext ctx) { - BeanMapping beanMapping = method.getMappingOptions().getBeanMapping(); - if ( beanMapping != null && beanMapping.getBuilder() != null ) { - return beanMapping.getBuilder(); - } - return MapperConfiguration.getInstanceOn( ctx.getMapperTypeElement() ).getBuilderPrism(); - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java index 7973b5c8d4..5c99b85588 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/CollectionAssignmentBuilder.java @@ -1,38 +1,40 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; +import java.util.function.Predicate; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; + +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; import org.mapstruct.ap.internal.model.assignment.ExistingInstanceSetterWrapperForCollectionsAndMaps; import org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps; +import org.mapstruct.ap.internal.model.assignment.NewInstanceSetterWrapperForCollectionsAndMaps; import org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMaps; import org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMapsWithNullCheck; import org.mapstruct.ap.internal.model.assignment.UpdateWrapper; import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.Assignment.AssignmentType; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; -import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.NullabilityResolver; import org.mapstruct.ap.internal.util.accessor.Accessor; +import org.mapstruct.ap.internal.util.accessor.AccessorType; + +import static org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem.ALWAYS; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.IGNORE; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_DEFAULT; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_NULL; /** * A builder that is used for creating an assignment to a collection. @@ -67,9 +69,12 @@ public class CollectionAssignmentBuilder { private Accessor targetReadAccessor; private Type targetType; private String targetPropertyName; - private PropertyMapping.TargetWriteAccessorType targetAccessorType; + private AccessorType targetAccessorType; private Assignment assignment; private SourceRHS sourceRHS; + private NullValueCheckStrategyGem nvcs; + private NullValuePropertyMappingStrategyGem nvpms; + private NullabilityResolver.Nullability sourceJSpecifyNullability = NullabilityResolver.Nullability.UNKNOWN; public CollectionAssignmentBuilder mappingBuilderContext(MappingBuilderContext ctx) { this.ctx = ctx; @@ -96,7 +101,7 @@ public CollectionAssignmentBuilder targetPropertyName(String targetPropertyName) return this; } - public CollectionAssignmentBuilder targetAccessorType(PropertyMapping.TargetWriteAccessorType targetAccessorType) { + public CollectionAssignmentBuilder targetAccessorType(AccessorType targetAccessorType) { this.targetAccessorType = targetAccessorType; return this; } @@ -121,14 +126,32 @@ public CollectionAssignmentBuilder rightHandSide(SourceRHS sourceRHS) { return this; } + public CollectionAssignmentBuilder nullValueCheckStrategy( NullValueCheckStrategyGem nvcs ) { + this.nvcs = nvcs; + return this; + } + + public CollectionAssignmentBuilder nullValuePropertyMappingStrategy( NullValuePropertyMappingStrategyGem nvpms ) { + this.nvpms = nvpms; + return this; + } + + public CollectionAssignmentBuilder sourceJSpecifyNullability( + NullabilityResolver.Nullability sourceJSpecifyNullability + ) { + this.sourceJSpecifyNullability = sourceJSpecifyNullability != null + ? sourceJSpecifyNullability + : NullabilityResolver.Nullability.UNKNOWN; + return this; + } + public Assignment build() { Assignment result = assignment; - CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy(); - boolean targetImmutable = cms == CollectionMappingStrategyPrism.TARGET_IMMUTABLE || targetReadAccessor == null; + CollectionMappingStrategyGem cms = method.getOptions().getMapper().getCollectionMappingStrategy(); + boolean targetImmutable = cms == CollectionMappingStrategyGem.TARGET_IMMUTABLE || targetReadAccessor == null; - if ( targetAccessorType == PropertyMapping.TargetWriteAccessorType.SETTER || - targetAccessorType == PropertyMapping.TargetWriteAccessorType.FIELD ) { + if ( targetAccessorType == AccessorType.SETTER || targetAccessorType.isFieldAssignment() ) { if ( result.isCallingUpdateMethod() && !targetImmutable ) { @@ -147,10 +170,12 @@ public Assignment build() { result, method.getThrownTypes(), factoryMethod, - PropertyMapping.TargetWriteAccessorType.isFieldAssignment( targetAccessorType ), + targetAccessorType.isFieldAssignment(), targetType, true, - mapNullToDefault() + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT, + false ); } else if ( method.isUpdateMethod() && !targetImmutable ) { @@ -159,31 +184,57 @@ else if ( method.isUpdateMethod() && !targetImmutable ) { result, method.getThrownTypes(), targetType, - method.getMapperConfiguration().getNullValueCheckStrategy(), + nvcs, + nvpms, ctx.getTypeFactory(), - PropertyMapping.TargetWriteAccessorType.isFieldAssignment( targetAccessorType ), - mapNullToDefault() + targetAccessorType.isFieldAssignment() ); } - else if ( result.getType() == Assignment.AssignmentType.DIRECT || - method.getMapperConfiguration().getNullValueCheckStrategy() == NullValueCheckStrategyPrism.ALWAYS ) { + else if ( method.isUpdateMethod() && nvpms == IGNORE ) { result = new SetterWrapperForCollectionsAndMapsWithNullCheck( result, method.getThrownTypes(), targetType, ctx.getTypeFactory(), - PropertyMapping.TargetWriteAccessorType.isFieldAssignment( targetAccessorType ), - mapNullToDefault() + targetAccessorType.isFieldAssignment() ); } - else { + else if ( setterWrapperNeedsSourceNullCheck( result ) + && canBeMappedOrDirectlyAssigned( result ) ) { + + result = new SetterWrapperForCollectionsAndMapsWithNullCheck( + result, + method.getThrownTypes(), + targetType, + ctx.getTypeFactory(), + targetAccessorType.isFieldAssignment() + ); + } + else if ( canBeMappedOrDirectlyAssigned( result ) ) { + //TODO init default value + // target accessor is setter, so wrap the setter in setter map/ collection handling result = new SetterWrapperForCollectionsAndMaps( result, method.getThrownTypes(), targetType, - PropertyMapping.TargetWriteAccessorType.isFieldAssignment( targetAccessorType ) + targetAccessorType.isFieldAssignment() + ); + } + else if ( hasNoArgsConstructor() ) { + result = new NewInstanceSetterWrapperForCollectionsAndMaps( + result, + method.getThrownTypes(), + targetType, + ctx.getTypeFactory(), + targetAccessorType.isFieldAssignment() ); + } + else { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.PROPERTYMAPPING_NO_SUITABLE_COLLECTION_OR_MAP_CONSTRUCTOR, + targetType ); } } @@ -201,15 +252,94 @@ else if ( result.getType() == Assignment.AssignmentType.DIRECT || result, method.getThrownTypes(), targetType, - PropertyMapping.TargetWriteAccessorType.isFieldAssignment( targetAccessorType ) + nvpms, + targetAccessorType.isFieldAssignment() ); } return result; } - private boolean mapNullToDefault() { - return method.getMapperConfiguration().getNullValueMappingStrategy() - == NullValueMappingStrategyPrism.RETURN_DEFAULT; + private boolean canBeMappedOrDirectlyAssigned(Assignment result) { + return result.getType() != AssignmentType.DIRECT + || hasCopyConstructor() + || targetType.isEnumSet(); + } + + /** + * Checks whether the setter wrapper should include a null / presence check or not + * + * @param rhs the source right hand side + * @return whether to include a null / presence check or not + */ + private boolean setterWrapperNeedsSourceNullCheck(Assignment rhs) { + // JSpecify: source @NonNull means the value is guaranteed non-null, skip the wrapper + if ( sourceJSpecifyNullability == NullabilityResolver.Nullability.NON_NULL ) { + ctx.getMessager().note( 2, + Message.PROPERTYMAPPING_JSPECIFY_SKIP_NULL_CHECK_NON_NULL_SOURCE, + targetPropertyName ); + return false; + } + + if ( rhs.getSourcePresenceCheckerReference() != null ) { + // If there is a source presence check then we should do a null check + return true; + } + + if ( nvcs == ALWAYS ) { + // NullValueCheckStrategy is ALWAYS -> do a null check + return true; + } + + if ( rhs.getType().isDirect() ) { + return true; + } + + return false; + } + + private boolean hasCopyConstructor() { + return checkConstructorForPredicate( this::hasCopyConstructor ); + } + + private boolean hasNoArgsConstructor() { + return checkConstructorForPredicate( this::hasNoArgsConstructor ); + } + + private boolean checkConstructorForPredicate(Predicate predicate) { + if ( targetType.isCollectionOrMapType() ) { + if ( "java.util".equals( targetType.getPackageName() ) ) { + return true; + } + else { + Element sourceElement = targetType.getImplementationType() != null + ? targetType.getImplementationType().getTypeElement() + : targetType.getTypeElement(); + if ( sourceElement != null ) { + for ( Element element : sourceElement.getEnclosedElements() ) { + if ( element.getKind() == ElementKind.CONSTRUCTOR + && element.getModifiers().contains( Modifier.PUBLIC ) ) { + if ( predicate.test( element ) ) { + return true; + } + } + } + } + } + } + return false; + } + + private boolean hasNoArgsConstructor(Element element) { + return ( (ExecutableElement) element ).getParameters().isEmpty(); + } + + private boolean hasCopyConstructor(Element element) { + if ( element instanceof ExecutableElement ) { + ExecutableElement ee = (ExecutableElement) element; + return ee.getParameters().size() == 1 + && ctx.getTypeUtils().isAssignable( targetType.getTypeMirror(), ee.getParameters().get( 0 ).asType() ); + } + return false; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Constructor.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Constructor.java index 0f07dd528a..a352a36063 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Constructor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Constructor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java index 1bb72088a7..1a807725d3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethod.java @@ -1,29 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Set; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; @@ -42,30 +31,50 @@ public abstract class ContainerMappingMethod extends NormalTypeMappingMethod { private final SelectionParameters selectionParameters; private final String index1Name; private final String index2Name; + private final Parameter sourceParameter; + private final PresenceCheck sourceParameterPresenceCheck; private IterableCreation iterableCreation; - ContainerMappingMethod(Method method, Collection existingVariables, Assignment parameterAssignment, + //CHECKSTYLE:OFF + ContainerMappingMethod(Method method, List annotations, + Collection existingVariables, Assignment parameterAssignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, - SelectionParameters selectionParameters) { - super( method, existingVariables, factoryMethod, mapNullToDefault, beforeMappingReferences, + SelectionParameters selectionParameters, PresenceCheck sourceParameterPresenceCheck) { + //CHECKSTYLE:ON + super( method, annotations, existingVariables, factoryMethod, mapNullToDefault, beforeMappingReferences, afterMappingReferences ); this.elementAssignment = parameterAssignment; this.loopVariableName = loopVariableName; - this.selectionParameters = selectionParameters; - this.index1Name = Strings.getSaveVariableName( "i", existingVariables ); - this.index2Name = Strings.getSaveVariableName( "j", existingVariables ); - } + this.selectionParameters = selectionParameters != null ? selectionParameters : SelectionParameters.empty(); - public Parameter getSourceParameter() { + this.index1Name = Strings.getSafeVariableName( "i", existingVariables ); + this.index2Name = Strings.getSafeVariableName( "j", existingVariables ); + + Parameter sourceParameter = null; for ( Parameter parameter : getParameters() ) { if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { - return parameter; + sourceParameter = parameter; + break; } } - throw new IllegalStateException( "Method " + this + " has no source parameter." ); + if ( sourceParameter == null ) { + throw new IllegalStateException( "Method " + this + " has no source parameter." ); + } + + this.sourceParameter = sourceParameter; + this.sourceParameterPresenceCheck = sourceParameterPresenceCheck; + + } + + public Parameter getSourceParameter() { + return sourceParameter; + } + + public PresenceCheck getSourceParameterPresenceCheck() { + return sourceParameterPresenceCheck; } public IterableCreation getIterableCreation() { @@ -130,12 +139,7 @@ public boolean equals(Object obj) { ContainerMappingMethod other = (ContainerMappingMethod) obj; - if ( this.selectionParameters != null ) { - if ( !this.selectionParameters.equals( other.selectionParameters ) ) { - return false; - } - } - else if ( other.selectionParameters != null ) { + if ( !Objects.equals( selectionParameters, other.selectionParameters ) ) { return false; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java index 5a3d5dde16..598db971e2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ContainerMappingMethodBuilder.java @@ -1,40 +1,30 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.Collection; import java.util.HashSet; import java.util.List; import java.util.Set; +import javax.lang.model.element.AnnotationMirror; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.FormattingParameters; +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; +import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; +import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; +import static org.mapstruct.ap.internal.util.Collections.first; + /** * Builder that can be used to build {@link ContainerMappingMethod}(s). * @@ -48,9 +38,9 @@ public abstract class ContainerMappingMethodBuilder selfType, String errorMessagePart) { super( selfType ); @@ -67,13 +57,13 @@ public B selectionParameters(SelectionParameters selectionParameters) { return myself; } - public B nullValueMappingStrategy(NullValueMappingStrategyPrism nullValueMappingStrategy) { - this.nullValueMappingStrategy = nullValueMappingStrategy; + public B callingContextTargetPropertyName(String callingContextTargetPropertyName) { + this.callingContextTargetPropertyName = callingContextTargetPropertyName; return myself; } - public B callingContextTargetPropertyName(String callingContextTargetPropertyName) { - this.callingContextTargetPropertyName = callingContextTargetPropertyName; + public B positionHint(AnnotationMirror positionHint) { + this.positionHint = positionHint; return myself; } @@ -86,28 +76,31 @@ public final M build() { Type targetElementType = getElementType( resultType ); String loopVariableName = - Strings.getSaveVariableName( sourceElementType.getName(), method.getParameterNames() ); + Strings.getSafeVariableName( sourceElementType.getName(), method.getParameterNames() ); SourceRHS sourceRHS = new SourceRHS( loopVariableName, sourceElementType, - new HashSet(), + new HashSet<>(), errorMessagePart ); - Assignment assignment = ctx.getMappingResolver().getTargetAssignment( - method, + + SelectionCriteria criteria = SelectionCriteria.forMappingMethods( selectionParameters, + method.getOptions().getIterableMapping().getMappingControl( ctx.getElementUtils() ), + callingContextTargetPropertyName, + false + ); + + Assignment assignment = ctx.getMappingResolver().getTargetAssignment( method, + getDescription(), targetElementType, - callingContextTargetPropertyName, formattingParameters, - selectionParameters, + criteria, sourceRHS, - false + positionHint, + () -> forge( sourceRHS, sourceElementType, targetElementType ) ); - if ( assignment == null ) { - assignment = forgeMapping( sourceRHS, sourceElementType, targetElementType ); - } - if ( assignment == null ) { if ( method instanceof ForgedMethod ) { // leave messaging to calling property mapping @@ -116,32 +109,43 @@ public final M build() { else { reportCannotCreateMapping( method, - String.format( "%s \"%s\"", sourceRHS.getSourceErrorMessagePart(), sourceRHS.getSourceType() ), + String.format( "%s \"%s\"", sourceRHS.getSourceErrorMessagePart(), + sourceRHS.getSourceType().describe() ), sourceRHS.getSourceType(), targetElementType, "" ); } } - else if ( method instanceof ForgedMethod ) { - ForgedMethod forgedMethod = (ForgedMethod) method; - forgedMethod.addThrownTypes( assignment.getThrownTypes() ); + else { + ctx.getMessager().note( 2, Message.ITERABLEMAPPING_SELECT_ELEMENT_NOTE, assignment ); + if ( method instanceof ForgedMethod ) { + ForgedMethod forgedMethod = (ForgedMethod) method; + forgedMethod.addThrownTypes( assignment.getThrownTypes() ); + } } - assignment = getWrapper( assignment, method ); - // mapNullToDefault - boolean mapNullToDefault = false; - if ( method.getMapperConfiguration() != null ) { - mapNullToDefault = method.getMapperConfiguration().isMapToDefault( nullValueMappingStrategy ); + // mapNullToDefault — a JSpecify @NonNull return forces RETURN_DEFAULT to avoid generating `return null`. + // Forcing is unconditional here (unlike BeanMappingMethod): when the source is @NonNull the template skips + // the whole guard block via `sourceParameterPresenceCheck??`, so the forced value is simply unused there. + boolean mapNullToDefault = method.getOptions() + .getIterableMapping() + .getNullValueMappingStrategy() + .isReturnDefault(); + if ( !mapNullToDefault && ctx.isJSpecifyNonNullReturn( method ) ) { + ctx.getMessager().note( 2, + Message.MAPPING_METHOD_JSPECIFY_FORCE_RETURN_DEFAULT, + method.getName() ); + mapNullToDefault = true; } MethodReference factoryMethod = null; if ( !method.isUpdateMethod() ) { - factoryMethod = ObjectFactoryMethodResolver.getFactoryMethod( method, method.getResultType(), null, ctx ); + factoryMethod = ObjectFactoryMethodResolver.getFactoryMethod( method, null, ctx ); } - Set existingVariables = new HashSet( method.getParameterNames() ); + Set existingVariables = new HashSet<>( method.getParameterNames() ); existingVariables.add( loopVariableName ); List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( @@ -157,6 +161,11 @@ else if ( method instanceof ForgedMethod ) { existingVariables ); + // Resolve presence check via JSpecify-aware resolver — returns null when source is @NonNull. + Parameter sourceParam = first( method.getSourceParameters() ); + PresenceCheck sourceParameterPresenceCheck = + PresenceCheckMethodResolver.getPresenceCheckForSourceParameter( method, null, sourceParam, ctx ); + return instantiateMappingMethod( method, existingVariables, @@ -166,16 +175,25 @@ else if ( method instanceof ForgedMethod ) { loopVariableName, beforeMappingMethods, afterMappingMethods, - selectionParameters + selectionParameters, + sourceParameterPresenceCheck ); } + private Assignment forge(SourceRHS sourceRHS, Type sourceType, Type targetType) { + Assignment assignment = super.forgeMapping( sourceRHS, sourceType, targetType ); + if ( assignment != null ) { + ctx.getMessager().note( 2, Message.ITERABLEMAPPING_CREATE_ELEMENT_NOTE, assignment ); + } + return assignment; + } + protected abstract M instantiateMappingMethod(Method method, Collection existingVariables, Assignment assignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingMethods, List afterMappingMethods, - SelectionParameters selectionParameters); + SelectionParameters selectionParameters, PresenceCheck sourceParameterPresenceCheck); protected abstract Type getElementType(Type parameterType); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Decorator.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Decorator.java index ae67c4ff29..df7940da31 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Decorator.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Decorator.java @@ -1,36 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.Arrays; import java.util.List; +import java.util.Set; import java.util.SortedSet; - -import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; +import org.mapstruct.ap.internal.gem.DecoratedWithGem; import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.option.Options; -import org.mapstruct.ap.internal.prism.DecoratedWithPrism; import org.mapstruct.ap.internal.version.VersionInformation; /** @@ -40,28 +25,19 @@ */ public class Decorator extends GeneratedType { - public static class Builder { + public static class Builder extends GeneratedTypeBuilder { - private Elements elementUtils; - private TypeFactory typeFactory; private TypeElement mapperElement; - private DecoratedWithPrism decoratorPrism; - private List methods; - private Options options; - private VersionInformation versionInformation; + private DecoratedWithGem decorator; + private boolean hasDelegateConstructor; private String implName; private String implPackage; - private SortedSet extraImportedTypes; - - public Builder elementUtils(Elements elementUtils) { - this.elementUtils = elementUtils; - return this; - } + private boolean suppressGeneratorTimestamp; + private Set customAnnotations; - public Builder typeFactory(TypeFactory typeFactory) { - this.typeFactory = typeFactory; - return this; + public Builder() { + super( Builder.class ); } public Builder mapperElement(TypeElement mapperElement) { @@ -69,23 +45,8 @@ public Builder mapperElement(TypeElement mapperElement) { return this; } - public Builder decoratorPrism(DecoratedWithPrism decoratorPrism) { - this.decoratorPrism = decoratorPrism; - return this; - } - - public Builder methods(List methods) { - this.methods = methods; - return this; - } - - public Builder options(Options options) { - this.options = options; - return this; - } - - public Builder versionInformation(VersionInformation versionInformation) { - this.versionInformation = versionInformation; + public Builder decoratedWith(DecoratedWithGem decoratedGem) { + this.decorator = decoratedGem; return this; } @@ -104,23 +65,29 @@ public Builder implPackage(String implPackage) { return this; } - public Builder extraImports(SortedSet extraImportedTypes) { - this.extraImportedTypes = extraImportedTypes; + public Builder suppressGeneratorTimestamp(boolean suppressGeneratorTimestamp) { + this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; + return this; + } + + public Builder additionalAnnotations(Set customAnnotations) { + this.customAnnotations = customAnnotations; return this; } public Decorator build() { String implementationName = implName.replace( Mapper.CLASS_NAME_PLACEHOLDER, - Mapper.getFlatName( mapperElement ) ); + Mapper.getFlatName( mapperElement ) ); - Type decoratorType = typeFactory.getType( decoratorPrism.value() ); + Type decoratorType = typeFactory.getType( decorator.value().get() ); DecoratorConstructor decoratorConstructor = new DecoratorConstructor( - implementationName, - implementationName + "_", - hasDelegateConstructor ); + implementationName, + implementationName + "_", + hasDelegateConstructor ); - String elementPackage = elementUtils.getPackageOf( mapperElement ).getQualifiedName().toString(); + Type mapperType = typeFactory.getType( mapperElement ); + String elementPackage = mapperType.getPackageName(); String packageName = implPackage.replace( Mapper.PACKAGE_NAME_PLACEHOLDER, elementPackage ); return new Decorator( @@ -128,50 +95,74 @@ public Decorator build() { packageName, implementationName, decoratorType, - elementPackage, - mapperElement.getKind() == ElementKind.INTERFACE ? mapperElement.getSimpleName().toString() : null, + mapperType, methods, - Arrays.asList( new Field( typeFactory.getType( mapperElement ), "delegate", true ) ), options, versionInformation, + suppressGeneratorTimestamp, Accessibility.fromModifiers( mapperElement.getModifiers() ), extraImportedTypes, - decoratorConstructor + decoratorConstructor, + customAnnotations ); } } private final Type decoratorType; + private final Type mapperType; @SuppressWarnings( "checkstyle:parameternumber" ) private Decorator(TypeFactory typeFactory, String packageName, String name, Type decoratorType, - String interfacePackage, String interfaceName, List methods, - List fields, Options options, VersionInformation versionInformation, + Type mapperType, + List methods, + Options options, VersionInformation versionInformation, + boolean suppressGeneratorTimestamp, Accessibility accessibility, SortedSet extraImports, - DecoratorConstructor decoratorConstructor) { + DecoratorConstructor decoratorConstructor, + Set customAnnotations) { super( typeFactory, packageName, name, - decoratorType.getName(), - interfacePackage, - interfaceName, + decoratorType, methods, - fields, + Arrays.asList( new Field( mapperType, "delegate", true ) ), options, versionInformation, + suppressGeneratorTimestamp, accessibility, extraImports, decoratorConstructor ); this.decoratorType = decoratorType; + this.mapperType = mapperType; + + // Add custom annotations + if ( customAnnotations != null ) { + customAnnotations.forEach( this::addAnnotation ); + } } @Override public SortedSet getImportTypes() { SortedSet importTypes = super.getImportTypes(); - addIfImportRequired( importTypes, decoratorType ); + // DecoratorType needs special handling in case it is nested + // calling addIfImportRequired is not the most correct approach since it would + // lead to checking if the type is to be imported and that would be false + // since the Decorator is a nested class within the Mapper. + // However, when generating the Decorator this is not needed, + // because the Decorator is a top level class itself + // In a nutshell creating the Decorator should have its own ProcessorContext, but it doesn't + if ( decoratorType.getPackageName().equalsIgnoreCase( getPackageName() ) ) { + if ( decoratorType.getTypeElement() != null && + decoratorType.getTypeElement().getNestingKind().isNested() ) { + importTypes.add( decoratorType ); + } + } + else { + importTypes.add( decoratorType ); + } return importTypes; } @@ -179,4 +170,8 @@ public SortedSet getImportTypes() { protected String getTemplateName() { return getTemplateNameForClass( GeneratedType.class ); } + + public Type getMapperType() { + return mapperType; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/DecoratorConstructor.java b/processor/src/main/java/org/mapstruct/ap/internal/model/DecoratorConstructor.java index 89ff477ea1..3bdfd66435 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/DecoratorConstructor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/DecoratorConstructor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMapperReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMapperReference.java index c012a1ddad..2728f99323 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMapperReference.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMapperReference.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -34,28 +21,31 @@ */ public class DefaultMapperReference extends MapperReference { + private final boolean isSingleton; private final boolean isAnnotatedMapper; private final Set importTypes; - private DefaultMapperReference(Type type, boolean isAnnotatedMapper, Set importTypes, String variableName) { + private DefaultMapperReference(Type type, boolean isAnnotatedMapper, boolean isSingleton, + Set importTypes, String variableName) { super( type, variableName ); this.isAnnotatedMapper = isAnnotatedMapper; this.importTypes = importTypes; + this.isSingleton = isSingleton; } - public static DefaultMapperReference getInstance(Type type, boolean isAnnotatedMapper, TypeFactory typeFactory, - List otherMapperReferences) { + public static DefaultMapperReference getInstance(Type type, boolean isAnnotatedMapper, boolean isSingleton, + TypeFactory typeFactory, List otherMapperReferences) { Set importTypes = Collections.asSet( type ); - if ( isAnnotatedMapper ) { + if ( isAnnotatedMapper && !isSingleton ) { importTypes.add( typeFactory.getType( "org.mapstruct.factory.Mappers" ) ); } - String variableName = Strings.getSaveVariableName( + String variableName = Strings.getSafeVariableName( type.getName(), otherMapperReferences ); - return new DefaultMapperReference( type, isAnnotatedMapper, importTypes, variableName ); + return new DefaultMapperReference( type, isAnnotatedMapper, isSingleton, importTypes, variableName ); } @Override @@ -66,4 +56,9 @@ public Set getImportTypes() { public boolean isAnnotatedMapper() { return isAnnotatedMapper; } + + public boolean isSingleton() { + return isSingleton; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMappingExclusionProvider.java b/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMappingExclusionProvider.java index 66656e6ea2..c5a97cf860 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMappingExclusionProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/DefaultMappingExclusionProvider.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/DelegatingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/DelegatingMethod.java index 0bc6260511..4d5b8efe17 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/DelegatingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/DelegatingMethod.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/EnumMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/EnumMappingMethod.java deleted file mode 100644 index fc0a896606..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/EnumMappingMethod.java +++ /dev/null @@ -1,214 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model; - -import static org.mapstruct.ap.internal.util.Collections.first; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.source.EnumMapping; -import org.mapstruct.ap.internal.model.source.Mapping; -import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.model.source.SelectionParameters; -import org.mapstruct.ap.internal.model.source.SourceMethod; -import org.mapstruct.ap.internal.prism.BeanMappingPrism; -import org.mapstruct.ap.internal.util.Message; -import org.mapstruct.ap.internal.util.Strings; - -/** - * A {@link MappingMethod} which maps one enum type to another, optionally configured by one or more - * {@link EnumMapping}s. - * - * @author Gunnar Morling - */ -public class EnumMappingMethod extends MappingMethod { - - private final List enumMappings; - - public static class Builder { - - private SourceMethod method; - private MappingBuilderContext ctx; - - public Builder mappingContext(MappingBuilderContext mappingContext) { - this.ctx = mappingContext; - return this; - } - - public Builder sourceMethod(SourceMethod sourceMethod) { - this.method = sourceMethod; - return this; - } - - public EnumMappingMethod build() { - - if ( !reportErrorIfMappedEnumConstantsDontExist( method ) - || !reportErrorIfSourceEnumConstantsWithoutCorrespondingTargetConstantAreNotMapped( method ) ) { - return null; - } - - List enumMappings = new ArrayList(); - - List sourceEnumConstants = first( method.getSourceParameters() ).getType().getEnumConstants(); - - for ( String enumConstant : sourceEnumConstants ) { - List mappedConstants = method.getMappingBySourcePropertyName( enumConstant ); - - if ( mappedConstants.isEmpty() ) { - enumMappings.add( new EnumMapping( enumConstant, enumConstant ) ); - } - else if ( mappedConstants.size() == 1 ) { - enumMappings.add( - new EnumMapping( - enumConstant, first( mappedConstants ).getTargetName() - ) - ); - } - else { - List targetConstants = new ArrayList( mappedConstants.size() ); - for ( Mapping mapping : mappedConstants ) { - targetConstants.add( mapping.getTargetName() ); - } - ctx.getMessager().printMessage( method.getExecutable(), - Message.ENUMMAPPING_MULTIPLE_SOURCES, - enumConstant, - Strings.join( targetConstants, ", " ) - ); - } - } - - SelectionParameters selectionParameters = getSelecionParameters( method, ctx.getTypeUtils() ); - - Set existingVariables = new HashSet( method.getParameterNames() ); - List beforeMappingMethods = - LifecycleMethodResolver.beforeMappingMethods( method, selectionParameters, ctx, existingVariables ); - List afterMappingMethods = - LifecycleMethodResolver.afterMappingMethods( method, selectionParameters, ctx, existingVariables ); - - return new EnumMappingMethod( method, enumMappings, beforeMappingMethods, afterMappingMethods ); - } - - private static SelectionParameters getSelecionParameters(SourceMethod method, Types typeUtils) { - BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() ); - if ( beanMappingPrism != null ) { - List qualifiers = beanMappingPrism.qualifiedBy(); - List qualifyingNames = beanMappingPrism.qualifiedByName(); - TypeMirror resultType = beanMappingPrism.resultType(); - return new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); - } - return null; - } - - private boolean reportErrorIfMappedEnumConstantsDontExist(SourceMethod method) { - List sourceEnumConstants = first( method.getSourceParameters() ).getType().getEnumConstants(); - List targetEnumConstants = method.getReturnType().getEnumConstants(); - - boolean foundIncorrectMapping = false; - - for ( List mappedConstants : method.getMappingOptions().getMappings().values() ) { - for ( Mapping mappedConstant : mappedConstants ) { - - if ( mappedConstant.getSourceName() == null ) { - ctx.getMessager().printMessage( method.getExecutable(), - mappedConstant.getMirror(), - Message.ENUMMAPPING_UNDEFINED_SOURCE - ); - foundIncorrectMapping = true; - } - else if ( !sourceEnumConstants.contains( mappedConstant.getSourceName() ) ) { - ctx.getMessager().printMessage( method.getExecutable(), - mappedConstant.getMirror(), - mappedConstant.getSourceAnnotationValue(), - Message.ENUMMAPPING_NON_EXISTING_CONSTANT, - mappedConstant.getSourceName(), - first( method.getSourceParameters() ).getType() - ); - foundIncorrectMapping = true; - } - if ( mappedConstant.getTargetName() == null ) { - ctx.getMessager().printMessage( method.getExecutable(), - mappedConstant.getMirror(), - Message.ENUMMAPPING_UNDEFINED_TARGET - ); - foundIncorrectMapping = true; - } - else if ( !targetEnumConstants.contains( mappedConstant.getTargetName() ) ) { - ctx.getMessager().printMessage( method.getExecutable(), - mappedConstant.getMirror(), - mappedConstant.getTargetAnnotationValue(), - Message.ENUMMAPPING_NON_EXISTING_CONSTANT, - mappedConstant.getTargetName(), - method.getReturnType() - ); - foundIncorrectMapping = true; - } - } - } - - return !foundIncorrectMapping; - } - - private boolean reportErrorIfSourceEnumConstantsWithoutCorrespondingTargetConstantAreNotMapped( - SourceMethod method) { - - List sourceEnumConstants = first( method.getSourceParameters() ).getType().getEnumConstants(); - List targetEnumConstants = method.getReturnType().getEnumConstants(); - List unmappedSourceEnumConstants = new ArrayList(); - - for ( String sourceEnumConstant : sourceEnumConstants ) { - if ( !targetEnumConstants.contains( sourceEnumConstant ) - && method.getMappingBySourcePropertyName( sourceEnumConstant ).isEmpty() ) { - unmappedSourceEnumConstants.add( sourceEnumConstant ); - } - } - - if ( !unmappedSourceEnumConstants.isEmpty() ) { - ctx.getMessager().printMessage( method.getExecutable(), - Message.ENUMMAPPING_UNMAPPED_SOURCES, - Strings.join( unmappedSourceEnumConstants, ", " ) - ); - } - - return unmappedSourceEnumConstants.isEmpty(); - } - - } - - private EnumMappingMethod(Method method, List enumMappings, - List beforeMappingMethods, - List afterMappingMethods) { - super( method, beforeMappingMethods, afterMappingMethods ); - this.enumMappings = enumMappings; - } - - public List getEnumMappings() { - return enumMappings; - } - - public Parameter getSourceParameter() { - return first( getSourceParameters() ); - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Field.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Field.java index 654aa47ddd..b1d346d82c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Field.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Field.java @@ -1,24 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; +import java.util.Objects; import java.util.Set; import org.mapstruct.ap.internal.model.common.ModelElement; @@ -124,8 +114,15 @@ public boolean equals(Object obj) { return false; } final Field other = (Field) obj; - return !( (this.variableName == null) ? - (other.variableName != null) : !this.variableName.equals( other.variableName ) ); + return Objects.equals( variableName, other.variableName ); + } + + public static List getFieldNames(Set fields) { + List names = new ArrayList<>( fields.size() ); + for ( Field field : fields ) { + names.add( field.getVariableName() ); + } + return names; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java new file mode 100644 index 0000000000..fb7943ab24 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethod.java @@ -0,0 +1,442 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import javax.lang.model.element.ExecutableElement; + +import org.mapstruct.ap.internal.model.beanmapping.MappingReferences; +import org.mapstruct.ap.internal.model.common.Accessibility; +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.source.MappingMethodOptions; +import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; +import org.mapstruct.ap.internal.util.Strings; + +/** + * This method will be generated in absence of a suitable abstract method to implement. + * + * @author Sjaak Derksen + */ +public class ForgedMethod implements Method { + + private final List parameters; + private final Type returnType; + private final String name; + private final List thrownTypes; + private final ForgedMethodHistory history; + + private final List sourceParameters; + private final List contextParameters; + private final Parameter mappingTargetParameter; + private final MappingReferences mappingReferences; + + private final Method basedOn; + private final boolean forgedNameBased; + private MappingMethodOptions options; + + /** + * Creates a new forged method with the given name for mapping a method parameter to a property. + * + * @param name the (unique name) for this method + * @param sourceType the source type + * @param returnType the return type. + * @param basedOn the method that (originally) triggered this nested method generation. + * @return a new forge method + */ + public static ForgedMethod forParameterMapping(String name, Type sourceType, Type returnType, + Method basedOn) { + return new ForgedMethod( + name, + sourceType, + returnType, + Collections.emptyList(), + basedOn, + null, + MappingReferences.empty(), + false + ); + } + + /** + * Creates a new forged method for mapping a bean property to a property + * + * @param name the (unique name) for this method + * @param sourceType the source type + * @param returnType the return type. + * @param parameters other parameters (including the context + @MappingTarget + * @param basedOn the method that (originally) triggered this nested method generation. + * @param history a parent forged method if this is a forged method within a forged method + * @param mappingReferences the mapping options for this method + * @param forgedNameBased forges a name based (matched) mapping method + * @return a new forge method + */ + public static ForgedMethod forPropertyMapping(String name, Type sourceType, Type returnType, + List parameters, Method basedOn, + ForgedMethodHistory history, MappingReferences mappingReferences, + boolean forgedNameBased) { + return new ForgedMethod( + name, + sourceType, + returnType, + parameters, + basedOn, + history, + mappingReferences == null ? MappingReferences.empty() : mappingReferences, + forgedNameBased + ); + } + + /** + * Creates a new forged method for mapping a collection element, map key/value or stream element + * + * @param name the (unique name) for this method + * @param sourceType the source type + * @param returnType the return type. + * @param basedOn the method that (originally) triggered this nested method generation. + * @param history a parent forged method if this is a forged method within a forged method + * @param forgedNameBased forges a name based (matched) mapping method + * + * @return a new forge method + */ + public static ForgedMethod forElementMapping(String name, Type sourceType, Type returnType, Method basedOn, + ForgedMethodHistory history, boolean forgedNameBased) { + return new ForgedMethod( + name, + sourceType, + returnType, + basedOn.getContextParameters(), + basedOn, + history, + MappingReferences.empty(), + forgedNameBased + ); + } + + /** + * Creates a new forged method for mapping a SubclassMapping element + * + * @param name the (unique name) for this method + * @param sourceType the source type + * @param returnType the return type. + * @param basedOn the method that (originally) triggered this nested method generation. + * @param history a parent forged method if this is a forged method within a forged method + * @param forgedNameBased forges a name based (matched) mapping method + * + * @return a new forge method + */ + public static ForgedMethod forSubclassMapping(String name, Type sourceType, Type returnType, Method basedOn, + MappingReferences mappingReferences, ForgedMethodHistory history, + boolean forgedNameBased) { + return new ForgedMethod( + name, + sourceType, + returnType, + basedOn.getContextParameters(), + basedOn, + history, + mappingReferences == null ? MappingReferences.empty() : mappingReferences, + forgedNameBased, + MappingMethodOptions.getSubclassForgedMethodInheritedOptions( basedOn.getOptions() ) + ); + } + + private ForgedMethod(String name, Type sourceType, Type returnType, List additionalParameters, + Method basedOn, ForgedMethodHistory history, MappingReferences mappingReferences, + boolean forgedNameBased) { + this( + name, + sourceType, + returnType, + additionalParameters, + basedOn, + history, + mappingReferences, + forgedNameBased, + MappingMethodOptions.getForgedMethodInheritedOptions( basedOn.getOptions() ) + ); + } + + private ForgedMethod(String name, Type sourceType, Type returnType, List additionalParameters, + Method basedOn, ForgedMethodHistory history, MappingReferences mappingReferences, + boolean forgedNameBased, MappingMethodOptions options) { + + // establish name + String sourceParamSafeName; + if ( additionalParameters.isEmpty() ) { + sourceParamSafeName = Strings.getSafeVariableName( sourceType.getName() ); + } + else { + sourceParamSafeName = Strings.getSafeVariableName( + sourceType.getName(), + additionalParameters.stream().map( Parameter::getName ).collect( Collectors.toList() ) + ); + } + + // establish parameters + this.parameters = new ArrayList<>( 1 + additionalParameters.size() ); + Parameter sourceParameter = new Parameter( sourceParamSafeName, sourceType ); + this.parameters.add( sourceParameter ); + this.parameters.addAll( additionalParameters ); + this.sourceParameters = Parameter.getSourceParameters( parameters ); + this.contextParameters = Parameter.getContextParameters( parameters ); + this.mappingTargetParameter = Parameter.getMappingTargetParameter( parameters ); + this.returnType = returnType; + this.thrownTypes = new ArrayList<>(); + + // based on method + this.basedOn = basedOn; + + this.name = Strings.sanitizeIdentifierName( name ); + this.history = history; + this.mappingReferences = mappingReferences; + this.forgedNameBased = forgedNameBased; + + this.options = options; + } + + /** + * creates a new ForgedMethod with the same arguments but with a new name + * @param name the new name + * @param forgedMethod existing forge method + */ + public ForgedMethod(String name, ForgedMethod forgedMethod) { + this.parameters = forgedMethod.parameters; + this.returnType = forgedMethod.returnType; + this.thrownTypes = forgedMethod.thrownTypes; + this.history = forgedMethod.history; + + this.sourceParameters = Parameter.getSourceParameters( parameters ); + this.contextParameters = Parameter.getContextParameters( parameters ); + this.mappingTargetParameter = Parameter.getMappingTargetParameter( parameters ); + this.mappingReferences = forgedMethod.mappingReferences; + + this.basedOn = forgedMethod.basedOn; + + this.name = name; + this.forgedNameBased = forgedMethod.forgedNameBased; + + this.options = MappingMethodOptions.getForgedMethodInheritedOptions( basedOn.getOptions() ); + } + + @Override + public boolean matches(List sourceTypes, Type targetType) { + + if ( !targetType.equals( returnType ) ) { + return false; + } + + if ( parameters.size() != sourceTypes.size() ) { + return false; + } + + Iterator srcTypeIt = sourceTypes.iterator(); + Iterator paramIt = parameters.iterator(); + + while ( srcTypeIt.hasNext() && paramIt.hasNext() ) { + Type sourceType = srcTypeIt.next(); + Parameter param = paramIt.next(); + if ( !sourceType.equals( param.getType() ) ) { + return false; + } + } + + return true; + } + + @Override + public Type getDeclaringMapper() { + return null; + } + + @Override + public String getName() { + return name; + } + + @Override + public List getParameters() { + return parameters; + } + + @Override + public List getSourceParameters() { + return sourceParameters; + } + + @Override + public List getContextParameters() { + return contextParameters; + } + + @Override + public ParameterProvidedMethods getContextProvidedMethods() { + return basedOn.getContextProvidedMethods(); + } + + @Override + public Parameter getMappingTargetParameter() { + return mappingTargetParameter; + } + + @Override + public Parameter getTargetTypeParameter() { + return null; + } + + @Override + public Accessibility getAccessibility() { + return Accessibility.PROTECTED; + } + + @Override + public Type getReturnType() { + return returnType; + } + + @Override + public List getThrownTypes() { + return thrownTypes; + } + + public ForgedMethodHistory getHistory() { + return history; + } + + public boolean isForgedNamedBased() { + return forgedNameBased; + } + + public void addThrownTypes(List thrownTypesToAdd) { + for ( Type thrownType : thrownTypesToAdd ) { + // make sure there are no duplicates coming from the keyAssignment thrown types. + if ( !thrownTypes.contains( thrownType ) ) { + thrownTypes.add( thrownType ); + } + } + } + + @Override + public Type getResultType() { + return mappingTargetParameter != null ? mappingTargetParameter.getType() : returnType; + } + + @Override + public List getParameterNames() { + List parameterNames = new ArrayList<>(); + for ( Parameter parameter : getParameters() ) { + parameterNames.add( parameter.getName() ); + } + return parameterNames; + } + + @Override + public boolean overridesMethod() { + return false; + } + + @Override + public ExecutableElement getExecutable() { + return basedOn.getExecutable(); + } + + @Override + public boolean isLifecycleCallbackMethod() { + return false; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder( returnType.toString() ); + sb.append( " " ); + + sb.append( getName() ).append( "(" ).append( Strings.join( parameters, ", " ) ).append( ")" ); + + return sb.toString(); + } + + @Override + public boolean isStatic() { + return false; + } + + @Override + public boolean isDefault() { + return false; + } + + @Override + public Type getDefiningType() { + return null; + } + + @Override + public boolean isUpdateMethod() { + return getMappingTargetParameter() != null; + } + + /** + * object factory mechanism not supported for forged methods + * + * @return false + */ + @Override + public boolean isObjectFactory() { + return false; + } + + @Override + public MappingMethodOptions getOptions() { + return options; + } + + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + + @Override + public String describe() { + // the name of the forged method is never fully qualified, so no need to distinguish + // between verbose or not. The type knows whether it should log verbose + return getResultType().describe() + ":" + getName() + "(" + getMappingSourceType().describe() + ")"; + } + + public MappingReferences getMappingReferences() { + return mappingReferences; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + ForgedMethod that = (ForgedMethod) o; + + if ( !Objects.equals( parameters, that.parameters ) ) { + return false; + } + return Objects.equals( returnType, that.returnType ); + + } + + @Override + public int hashCode() { + int result = parameters != null ? parameters.hashCode() : 0; + result = 31 * result + ( returnType != null ? returnType.hashCode() : 0 ); + return result; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ForgedMethodHistory.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethodHistory.java similarity index 80% rename from processor/src/main/java/org/mapstruct/ap/internal/model/source/ForgedMethodHistory.java rename to processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethodHistory.java index 754866bafa..3463413705 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ForgedMethodHistory.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ForgedMethodHistory.java @@ -1,22 +1,9 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ -package org.mapstruct.ap.internal.model.source; +package org.mapstruct.ap.internal.model; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.util.Strings; @@ -56,7 +43,7 @@ public Type getSourceType() { } public String createSourcePropertyErrorMessage() { - return conditionallyCapitalizedElementType() + " \"" + getSourceType() + " " + + return conditionallyCapitalizedElementType() + " \"" + getSourceType().describe() + " " + stripBrackets( getDottedSourceElement() ) + "\""; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/FromOptionalTypeConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/model/FromOptionalTypeConversion.java new file mode 100644 index 0000000000..e1c320e16b --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/FromOptionalTypeConversion.java @@ -0,0 +1,115 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.List; +import java.util.Set; + +import org.mapstruct.ap.internal.model.assignment.OptionalGetWrapper; +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * An inline conversion from an optional source to it's value. + * + * @author Filip Hrisafov + */ +public class FromOptionalTypeConversion extends ModelElement implements Assignment { + + private final Assignment conversionAssignment; + private final Type optionalType; + + public FromOptionalTypeConversion(Type optionalType, Assignment conversionAssignment) { + this.conversionAssignment = conversionAssignment; + this.optionalType = optionalType; + } + + @Override + public Set getImportTypes() { + return conversionAssignment.getImportTypes(); + } + + @Override + public List getThrownTypes() { + return conversionAssignment.getThrownTypes(); + } + + public Assignment getAssignment() { + return conversionAssignment; + } + + @Override + public String getSourceReference() { + return conversionAssignment.getSourceReference(); + } + + @Override + public boolean isSourceReferenceParameter() { + return conversionAssignment.isSourceReferenceParameter(); + } + + @Override + public PresenceCheck getSourcePresenceCheckerReference() { + return conversionAssignment.getSourcePresenceCheckerReference(); + } + + @Override + public Type getSourceType() { + return conversionAssignment.getSourceType(); + } + + @Override + public String createUniqueVarName(String desiredName) { + return conversionAssignment.createUniqueVarName( desiredName ); + } + + @Override + public String getSourceLocalVarName() { + return conversionAssignment.getSourceLocalVarName(); + } + + @Override + public void setSourceLocalVarName(String sourceLocalVarName) { + conversionAssignment.setSourceLocalVarName( sourceLocalVarName ); + } + + @Override + public String getSourceLoopVarName() { + return conversionAssignment.getSourceLoopVarName(); + } + + @Override + public void setSourceLoopVarName(String sourceLoopVarName) { + conversionAssignment.setSourceLoopVarName( sourceLoopVarName ); + } + + @Override + public String getSourceParameterName() { + return conversionAssignment.getSourceParameterName(); + } + + @Override + public void setAssignment(Assignment assignment) { + this.conversionAssignment.setAssignment( new OptionalGetWrapper( assignment, optionalType ) ); + } + + @Override + public AssignmentType getType() { + return conversionAssignment.getType(); + } + + @Override + public boolean isCallingUpdateMethod() { + return false; + } + + @Override + public String toString() { + return conversionAssignment.toString(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedType.java b/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedType.java index 592620997e..6eb8bbfef8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedType.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -23,14 +10,15 @@ import java.util.List; import java.util.SortedSet; import java.util.TreeSet; - import javax.lang.model.type.TypeKind; +import org.mapstruct.ap.internal.gem.ClassAccessibilityGem; import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.option.Options; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.Strings; import org.mapstruct.ap.internal.version.VersionInformation; @@ -43,21 +31,71 @@ public abstract class GeneratedType extends ModelElement { private static final String JAVA_LANG_PACKAGE = "java.lang"; + protected abstract static class GeneratedTypeBuilder> { + + private final T myself; + protected TypeFactory typeFactory; + protected ElementUtils elementUtils; + protected Options options; + protected VersionInformation versionInformation; + protected SortedSet extraImportedTypes; + + protected List methods; + protected ClassAccessibilityGem classAccessibility; + + GeneratedTypeBuilder(Class selfType) { + myself = selfType.cast( this ); + } + + public T elementUtils(ElementUtils elementUtils) { + this.elementUtils = elementUtils; + return myself; + } + + public T typeFactory(TypeFactory typeFactory) { + this.typeFactory = typeFactory; + return myself; + } + + public T options(Options options) { + this.options = options; + return myself; + } + + public T versionInformation(VersionInformation versionInformation) { + this.versionInformation = versionInformation; + return myself; + } + + public T extraImports(SortedSet extraImportedTypes) { + this.extraImportedTypes = extraImportedTypes; + return myself; + } + + public T methods(List methods) { + this.methods = methods; + return myself; + } + + public T classAccessibility(ClassAccessibilityGem classAccessibility) { + this.classAccessibility = classAccessibility; + return myself; + } + } + private final String packageName; private final String name; - private final String superClassName; - private final String interfacePackage; - private final String interfaceName; + private final Type mapperDefinitionType; private final List annotations; - private final List methods; + private final List methods; private final SortedSet extraImportedTypes; private final boolean suppressGeneratorTimestamp; private final boolean suppressGeneratorVersionComment; private final VersionInformation versionInformation; private final Accessibility accessibility; - private List fields; + private List fields; private Constructor constructor; /** @@ -67,32 +105,37 @@ public abstract class GeneratedType extends ModelElement { private final boolean generatedTypeAvailable; // CHECKSTYLE:OFF - protected GeneratedType(TypeFactory typeFactory, String packageName, String name, String superClassName, - String interfacePackage, String interfaceName, List methods, - List fields, Options options, VersionInformation versionInformation, + protected GeneratedType(TypeFactory typeFactory, String packageName, String name, + Type mapperDefinitionType, List methods, + List fields, Options options, VersionInformation versionInformation, + boolean suppressGeneratorTimestamp, Accessibility accessibility, SortedSet extraImportedTypes, Constructor constructor) { this.packageName = packageName; this.name = name; - this.superClassName = superClassName; - this.interfacePackage = interfacePackage; - this.interfaceName = interfaceName; + this.mapperDefinitionType = mapperDefinitionType; this.extraImportedTypes = extraImportedTypes; - this.annotations = new ArrayList(); - this.methods = methods; + this.annotations = new ArrayList<>(); + this.methods = new ArrayList<>(methods); this.fields = fields; - this.suppressGeneratorTimestamp = options.isSuppressGeneratorTimestamp(); + this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; this.suppressGeneratorVersionComment = options.isSuppressGeneratorVersionComment(); this.versionInformation = versionInformation; this.accessibility = accessibility; - this.generatedTypeAvailable = typeFactory.isTypeAvailable( "javax.annotation.Generated" ); - if ( generatedTypeAvailable ) { + if ( versionInformation.isSourceVersionAtLeast9() && + typeFactory.isTypeAvailable( "javax.annotation.processing.Generated" ) ) { + this.generatedType = typeFactory.getType( "javax.annotation.processing.Generated" ); + this.generatedTypeAvailable = true; + } + else if ( typeFactory.isTypeAvailable( "javax.annotation.Generated" ) ) { this.generatedType = typeFactory.getType( "javax.annotation.Generated" ); + this.generatedTypeAvailable = true; } else { this.generatedType = null; + this.generatedTypeAvailable = false; } this.constructor = constructor; @@ -112,16 +155,8 @@ public String getName() { return name; } - public String getSuperClassName() { - return superClassName; - } - - public String getInterfacePackage() { - return interfacePackage; - } - - public String getInterfaceName() { - return interfaceName; + public Type getMapperDefinitionType() { + return mapperDefinitionType; } public List getAnnotations() { @@ -132,15 +167,15 @@ public void addAnnotation(Annotation annotation) { annotations.add( annotation ); } - public List getMethods() { + public List getMethods() { return methods; } - public List getFields() { + public List getFields() { return fields; } - public void setFields(List fields) { + public void setFields(List fields) { this.fields = fields; } @@ -170,10 +205,12 @@ public void setConstructor(Constructor constructor) { @Override public SortedSet getImportTypes() { - SortedSet importedTypes = new TreeSet(); + SortedSet importedTypes = new TreeSet<>(); addIfImportRequired( importedTypes, generatedType ); - for ( MappingMethod mappingMethod : methods ) { + addIfImportRequired( importedTypes, mapperDefinitionType ); + + for ( GeneratedTypeMethod mappingMethod : methods ) { for ( Type type : mappingMethod.getImportTypes() ) { addIfImportRequired( importedTypes, type ); } @@ -188,7 +225,9 @@ public SortedSet getImportTypes() { } for ( Annotation annotation : annotations ) { - addIfImportRequired( importedTypes, annotation.getType() ); + for ( Type type : annotation.getImportTypes() ) { + addIfImportRequired( importedTypes, type ); + } } for ( Type extraImport : extraImportedTypes ) { @@ -205,7 +244,7 @@ public SortedSet getImportTypes() { } public SortedSet getImportTypeNames() { - SortedSet importTypeNames = new TreeSet(); + SortedSet importTypeNames = new TreeSet<>(); for ( Type type : getImportTypes() ) { importTypeNames.add( type.getImportName() ); } @@ -220,18 +259,24 @@ public void removeConstructor() { constructor = null; } + public Javadoc getJavadoc() { + return null; + } + protected void addIfImportRequired(Collection collection, Type typeToAdd) { if ( typeToAdd == null ) { return; } - if ( needsImportDeclaration( typeToAdd ) ) { - collection.add( typeToAdd ); + for ( Type type : typeToAdd.getImportTypes() ) { + if ( needsImportDeclaration( type ) ) { + collection.add( type ); + } } } private boolean needsImportDeclaration(Type typeToAdd) { - if ( !typeToAdd.isImported() ) { + if ( !typeToAdd.isToBeImported() ) { return false; } @@ -247,8 +292,15 @@ private boolean needsImportDeclaration(Type typeToAdd) { } if ( typeToAdd.getPackageName().equals( packageName ) ) { - if ( !typeToAdd.getTypeElement().getNestingKind().isNested() ) { - return false; + if ( typeToAdd.getTypeElement() != null ) { + if ( !typeToAdd.getTypeElement().getNestingKind().isNested() ) { + return false; + } + } + else if ( typeToAdd.getComponentType() != null ) { + if ( !typeToAdd.getComponentType().getTypeElement().getNestingKind().isNested() ) { + return false; + } } } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedTypeMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedTypeMethod.java new file mode 100644 index 0000000000..8d6a999665 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/GeneratedTypeMethod.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import org.mapstruct.ap.internal.model.common.ModelElement; + +/** + * Base class for methods available in a generated type. + * + * @author Filip Hrisafov + */ +public abstract class GeneratedTypeMethod extends ModelElement { + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java index 8121f7def7..6ff85c585f 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/HelperMethod.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -23,7 +10,6 @@ import java.util.Collections; import java.util.List; import java.util.Set; - import javax.lang.model.element.ExecutableElement; import org.mapstruct.ap.internal.model.common.Accessibility; @@ -32,7 +18,6 @@ import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; -import org.mapstruct.ap.internal.util.MapperConfiguration; import org.mapstruct.ap.internal.util.Strings; /** @@ -65,7 +50,7 @@ public String getName() { * @return the types used by this method for which import statements need to be generated */ public Set getImportTypes() { - return Collections.emptySet(); + return Collections.emptySet(); } /** @@ -143,6 +128,11 @@ public boolean isObjectFactory() { return false; } + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + /** * the conversion context is used to format an auxiliary parameter in the method call with context specific * information such as a date format. @@ -186,14 +176,12 @@ public boolean equals(Object obj) { * * @param parameter source * @param returnType target - * @return {@code true}, iff the the type variables match + * @return {@code true}, iff the type variables match */ public boolean doTypeVarsMatch(Type parameter, Type returnType) { return true; } - - /** * There's currently only one parameter foreseen instead of a list of parameter * @@ -218,7 +206,7 @@ public Type getResultType() { @Override public List getParameterNames() { - List parameterNames = new ArrayList( getParameters().size() ); + List parameterNames = new ArrayList<>( getParameters().size() ); for ( Parameter parameter : getParameters() ) { parameterNames.add( parameter.getName() ); } @@ -251,11 +239,6 @@ public Type getDefiningType() { return null; } - @Override - public MapperConfiguration getMapperConfiguration() { - return null; - } - @Override public boolean isLifecycleCallbackMethod() { return false; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableCreation.java b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableCreation.java index a1afac6f71..cf7bc6e2eb 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableCreation.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableCreation.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -22,9 +9,12 @@ import java.util.Set; import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.NewInstanceCreation; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; +import static org.mapstruct.ap.internal.util.Collections.first; + /** * Model element that can be used to create a type of {@link Iterable} or {@link java.util.Map}. If an implementation * type is used and the target type has a constructor with {@code int} as parameter and the source parameter is of @@ -38,6 +28,7 @@ public class IterableCreation extends ModelElement { private final Type resultType; private final Parameter sourceParameter; private final MethodReference factoryMethod; + private final NewInstanceCreation newInstance; private final boolean canUseSize; private final boolean loadFactorAdjustment; @@ -45,6 +36,7 @@ private IterableCreation(Type resultType, Parameter sourceParameter, MethodRefer this.resultType = resultType; this.sourceParameter = sourceParameter; this.factoryMethod = factoryMethod; + this.newInstance = factoryMethod == null ? NewInstanceCreation.forType( resultType ) : null; this.canUseSize = ( sourceParameter.getType().isCollectionOrMapType() || sourceParameter.getType().isArrayType() ) && resultType.getImplementation() != null && resultType.getImplementation().hasInitialCapacityConstructor(); @@ -68,6 +60,10 @@ public MethodReference getFactoryMethod() { return this.factoryMethod; } + public NewInstanceCreation getNewInstance() { + return newInstance; + } + public boolean isCanUseSize() { return canUseSize; } @@ -78,10 +74,24 @@ public boolean isLoadFactorAdjustment() { @Override public Set getImportTypes() { - Set types = new HashSet(); - if ( factoryMethod == null && resultType.getImplementationType() != null ) { - types.addAll( resultType.getImplementationType().getImportTypes() ); + Set types = new HashSet<>(); + if ( newInstance != null ) { + types.addAll( newInstance.getImportTypes() ); + } + + if ( isEnumSet() ) { + types.add( getEnumSetElementType() ); + // The result type itself is an EnumSet + types.add( resultType ); } return types; } + + public Type getEnumSetElementType() { + return first( getResultType().determineTypeArguments( Iterable.class ) ); + } + + public boolean isEnumSet() { + return "java.util.EnumSet".equals( resultType.getFullyQualifiedName() ); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java index d9f2b41cab..220466f802 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/IterableMappingMethod.java @@ -1,35 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.Collection; import java.util.List; +import java.util.Set; import org.mapstruct.ap.internal.model.assignment.LocalVarWrapper; import org.mapstruct.ap.internal.model.assignment.SetterWrapper; import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; +import static org.mapstruct.ap.internal.util.Collections.first; + /** * A {@link MappingMethod} implemented by a {@link Mapper} class which maps one iterable type to another. The collection * elements are mapped either by a {@link TypeConversion} or another mapping method. @@ -66,9 +55,11 @@ protected Assignment getWrapper(Assignment assignment, Method method) { protected IterableMappingMethod instantiateMappingMethod(Method method, Collection existingVariables, Assignment assignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingMethods, - List afterMappingMethods, SelectionParameters selectionParameters) { + List afterMappingMethods, SelectionParameters selectionParameters, + PresenceCheck sourceParameterPresenceCheck) { return new IterableMappingMethod( method, + getMethodAnnotations(), existingVariables, assignment, factoryMethod, @@ -76,18 +67,23 @@ protected IterableMappingMethod instantiateMappingMethod(Method method, Collecti loopVariableName, beforeMappingMethods, afterMappingMethods, - selectionParameters + selectionParameters, + sourceParameterPresenceCheck ); } } - private IterableMappingMethod(Method method, Collection existingVariables, Assignment parameterAssignment, + //CHECKSTYLE:OFF + private IterableMappingMethod(Method method, List annotations, + Collection existingVariables, Assignment parameterAssignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, - SelectionParameters selectionParameters) { + SelectionParameters selectionParameters, PresenceCheck sourceParameterPresenceCheck) { + //CHECKSTYLE:ON super( method, + annotations, existingVariables, parameterAssignment, factoryMethod, @@ -95,10 +91,19 @@ private IterableMappingMethod(Method method, Collection existingVariable loopVariableName, beforeMappingReferences, afterMappingReferences, - selectionParameters + selectionParameters, + sourceParameterPresenceCheck ); } + @Override + public Set getImportTypes() { + Set types = super.getImportTypes(); + + types.add( getSourceElementType() ); + return types; + } + public Type getSourceElementType() { Type sourceParameterType = getSourceParameter().getType(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Javadoc.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Javadoc.java new file mode 100644 index 0000000000..b8718b68e8 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Javadoc.java @@ -0,0 +1,92 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Collections; +import java.util.List; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * Represents the javadoc information that should be generated for a {@link Mapper}. + * + * @author Jose Carlos Campanero Ortiz + */ +public class Javadoc extends ModelElement { + + public static class Builder { + + private String value; + private List authors; + private String deprecated; + private String since; + + public Builder value(String value) { + this.value = value; + return this; + } + + public Builder authors(List authors) { + this.authors = authors; + return this; + } + + public Builder deprecated(String deprecated) { + this.deprecated = deprecated; + return this; + } + + public Builder since(String since) { + this.since = since; + return this; + } + + public Javadoc build() { + return new Javadoc( + value, + authors, + deprecated, + since + ); + } + } + + private final String value; + private final List authors; + private final String deprecated; + private final String since; + + private Javadoc(String value, List authors, String deprecated, String since) { + this.value = value; + this.authors = authors != null ? Collections.unmodifiableList( authors ) : Collections.emptyList(); + this.deprecated = deprecated; + this.since = since; + } + + public String getValue() { + return value; + } + + public List getAuthors() { + return authors; + } + + public String getDeprecated() { + return deprecated; + } + + public String getSince() { + return since; + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.java index 252655e741..c47fd258c0 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -55,7 +42,7 @@ private LifecycleCallbackMethodReference(SelectedMethod lifecycleM this.methodResultType = containingMethod.getResultType(); if ( hasReturnType() ) { - this.targetVariableName = Strings.getSaveVariableName( "target", existingVariableNames ); + this.targetVariableName = Strings.getSafeVariableName( "target", existingVariableNames ); existingVariableNames.add( this.targetVariableName ); } else { @@ -93,17 +80,11 @@ public String getTargetVariableName() { @Override public Set getImportTypes() { - return declaringType != null ? Collections.asSet( declaringType ) : java.util.Collections. emptySet(); + return declaringType != null ? Collections.asSet( declaringType ) : java.util.Collections.emptySet(); } public boolean hasMappingTargetParameter() { - for ( ParameterBinding param : getParameterBindings() ) { - if ( param.isMappingTarget() ) { - return true; - } - } - - return false; + return getParameterBindings().stream().anyMatch( ParameterBinding::isMappingTarget ); } /** diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleMethodResolver.java b/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleMethodResolver.java index 6c763e9c83..ada9dac470 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleMethodResolver.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/LifecycleMethodResolver.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -22,8 +9,11 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; @@ -31,7 +21,7 @@ import org.mapstruct.ap.internal.model.source.SourceMethod; import org.mapstruct.ap.internal.model.source.selector.MethodSelectors; import org.mapstruct.ap.internal.model.source.selector.SelectedMethod; -import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; +import org.mapstruct.ap.internal.model.source.selector.SelectionContext; /** * Factory for creating lists of appropriate {@link LifecycleCallbackMethodReference}s @@ -43,6 +33,51 @@ public final class LifecycleMethodResolver { private LifecycleMethodResolver() { } + /** + * @param method the method to obtain the beforeMapping methods for + * @param alternativeTarget alternative to {@link Method#getResultType()} e.g. when target is abstract + * @param selectionParameters method selectionParameters + * @param ctx the builder context + * @param existingVariableNames the existing variable names in the mapping method + * @return all applicable {@code @BeforeMapping} methods for the given method + */ + public static List beforeMappingMethods(Method method, + Type alternativeTarget, + SelectionParameters selectionParameters, + MappingBuilderContext ctx, + Set existingVariableNames) { + return collectLifecycleCallbackMethods( method, + alternativeTarget, + selectionParameters, + filterBeforeMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ), + ctx, + existingVariableNames ); + } + + /** + * @param method the method to obtain the afterMapping methods for + * @param alternativeTarget alternative to {@link Method#getResultType()} e.g. when target is abstract + * @param selectionParameters method selectionParameters + * @param ctx the builder context + * @param existingVariableNames list of already used variable names + * @return all applicable {@code @AfterMapping} methods for the given method + */ + public static List afterMappingMethods(Method method, + Type alternativeTarget, + SelectionParameters selectionParameters, + MappingBuilderContext ctx, + Set existingVariableNames, + Supplier> parameterBindingsProvider) { + return collectLifecycleCallbackMethods( method, + alternativeTarget, + selectionParameters, + filterAfterMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ), + ctx, + existingVariableNames, + parameterBindingsProvider + ); + } + /** * @param method the method to obtain the beforeMapping methods for * @param selectionParameters method selectionParameters @@ -55,6 +90,7 @@ public static List beforeMappingMethods(Method MappingBuilderContext ctx, Set existingVariableNames) { return collectLifecycleCallbackMethods( method, + method.getResultType(), selectionParameters, filterBeforeMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ), ctx, @@ -73,6 +109,7 @@ public static List afterMappingMethods(Method MappingBuilderContext ctx, Set existingVariableNames) { return collectLifecycleCallbackMethods( method, + method.getResultType(), selectionParameters, filterAfterMappingMethods( getAllAvailableMethods( method, ctx.getSourceModel() ) ), ctx, @@ -89,35 +126,46 @@ private static List getAllAvailableMethods(Method method, List availableMethods = - new ArrayList( methodsProvidedByParams.size() + sourceModelMethods.size() ); + new ArrayList<>( methodsProvidedByParams.size() + sourceModelMethods.size() ); - for ( SourceMethod methodProvidedByParams : methodsProvidedByParams ) { - availableMethods.add( methodProvidedByParams ); - } + availableMethods.addAll( methodsProvidedByParams ); availableMethods.addAll( sourceModelMethods ); return availableMethods; } private static List collectLifecycleCallbackMethods( - Method method, SelectionParameters selectionParameters, List callbackMethods, + Method method, Type targetType, SelectionParameters selectionParameters, List callbackMethods, MappingBuilderContext ctx, Set existingVariableNames) { + return collectLifecycleCallbackMethods( + method, + targetType, + selectionParameters, + callbackMethods, + ctx, + existingVariableNames, + Collections::emptyList + ); + } - MethodSelectors selectors = - new MethodSelectors( ctx.getTypeUtils(), ctx.getElementUtils(), ctx.getTypeFactory() ); - - Type targetType = method.getResultType(); + private static List collectLifecycleCallbackMethods( + Method method, Type targetType, SelectionParameters selectionParameters, List callbackMethods, + MappingBuilderContext ctx, Set existingVariableNames, + Supplier> parameterBindingsProvider) { - if ( !method.isUpdateMethod() ) { - targetType = targetType.getEffectiveType(); - } + MethodSelectors selectors = + new MethodSelectors( ctx.getTypeUtils(), ctx.getElementUtils(), ctx.getMessager(), ctx.getOptions() ); List> matchingMethods = selectors.getMatchingMethods( - method, callbackMethods, - Collections. emptyList(), - targetType, - SelectionCriteria.forLifecycleMethods( selectionParameters ) ); + SelectionContext.forLifecycleMethods( + method, + targetType, + selectionParameters, + ctx.getTypeFactory(), + parameterBindingsProvider + ) + ); return toLifecycleCallbackMethodRefs( method, @@ -131,7 +179,7 @@ private static List toLifecycleCallbackMethodR MappingBuilderContext ctx, Set existingVariableNames) { - List result = new ArrayList(); + List result = new ArrayList<>(); for ( SelectedMethod candidate : candidates ) { Parameter providingParameter = method.getContextProvidedMethods().getParameterForProvidedMethod( candidate.getMethod() ); @@ -159,24 +207,14 @@ private static List toLifecycleCallbackMethodR } private static List filterBeforeMappingMethods(List methods) { - List result = new ArrayList(); - for ( SourceMethod method : methods ) { - if ( method.isBeforeMappingMethod() ) { - result.add( method ); - } - } - - return result; + return methods.stream() + .filter( SourceMethod::isBeforeMappingMethod ) + .collect( Collectors.toList() ); } private static List filterAfterMappingMethods(List methods) { - List result = new ArrayList(); - for ( SourceMethod method : methods ) { - if ( method.isAfterMappingMethod() ) { - result.add( method ); - } - } - - return result; + return methods.stream() + .filter( SourceMethod::isAfterMappingMethod ) + .collect( Collectors.toList() ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java index 2c7fb453fc..5a49e3a726 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MapMappingMethod.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -30,14 +15,17 @@ import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; +import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; +import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; +import static org.mapstruct.ap.internal.util.Collections.first; + /** * A {@link MappingMethod} implemented by a {@link Mapper} class which maps one {@code Map} type to another. Keys and * values are mapped either by a {@link TypeConversion} or another mapping method if required. @@ -48,13 +36,14 @@ public class MapMappingMethod extends NormalTypeMappingMethod { private final Assignment keyAssignment; private final Assignment valueAssignment; + private final Parameter sourceParameter; + private final PresenceCheck sourceParameterPresenceCheck; private IterableCreation iterableCreation; public static class Builder extends AbstractMappingMethodBuilder { private FormattingParameters keyFormattingParameters; private FormattingParameters valueFormattingParameters; - private NullValueMappingStrategyPrism nullValueMappingStrategy; private SelectionParameters keySelectionParameters; private SelectionParameters valueSelectionParameters; @@ -82,11 +71,6 @@ public Builder valueFormattingParameters(FormattingParameters valueFormattingPar return this; } - public Builder nullValueMappingStrategy(NullValueMappingStrategyPrism nullValueMappingStrategy) { - this.nullValueMappingStrategy = nullValueMappingStrategy; - return this; - } - public MapMappingMethod build() { List sourceTypeParams = @@ -97,22 +81,26 @@ public MapMappingMethod build() { Type keySourceType = sourceTypeParams.get( 0 ).getTypeBound(); Type keyTargetType = resultTypeParams.get( 0 ).getTypeBound(); - SourceRHS keySourceRHS = new SourceRHS( "entry.getKey()", keySourceType, new HashSet(), "map key" ); + SourceRHS keySourceRHS = new SourceRHS( "entry.getKey()", keySourceType, new HashSet<>(), "map key" ); + + SelectionCriteria keyCriteria = SelectionCriteria.forMappingMethods( + keySelectionParameters, + method.getOptions().getMapMapping().getKeyMappingControl( ctx.getElementUtils() ), + null, + false + ); + Assignment keyAssignment = ctx.getMappingResolver().getTargetAssignment( method, + getDescription(), keyTargetType, - null, // there is no targetPropertyName keyFormattingParameters, - keySelectionParameters, + keyCriteria, keySourceRHS, - false + null, + () -> forge( keySourceRHS, keySourceType, keyTargetType, Message.MAPMAPPING_CREATE_KEY_NOTE ) ); - if ( keyAssignment == null ) { - keyAssignment = forgeMapping( keySourceRHS, keySourceType, keyTargetType ); - } - - if ( keyAssignment == null ) { if ( method instanceof ForgedMethod ) { // leave messaging to calling property mapping @@ -124,7 +112,7 @@ public MapMappingMethod build() { String.format( "%s \"%s\"", keySourceRHS.getSourceErrorMessagePart(), - keySourceRHS.getSourceType() + keySourceRHS.getSourceType().describe() ), keySourceRHS.getSourceType(), keyTargetType, @@ -132,21 +120,32 @@ public MapMappingMethod build() { ); } } + else { + ctx.getMessager().note( 2, Message.MAPMAPPING_SELECT_KEY_NOTE, keyAssignment ); + } // find mapping method or conversion for value Type valueSourceType = sourceTypeParams.get( 1 ).getTypeBound(); Type valueTargetType = resultTypeParams.get( 1 ).getTypeBound(); - SourceRHS valueSourceRHS = new SourceRHS( "entry.getValue()", valueSourceType, new HashSet(), + SourceRHS valueSourceRHS = new SourceRHS( "entry.getValue()", valueSourceType, new HashSet<>(), "map value" ); + + SelectionCriteria valueCriteria = SelectionCriteria.forMappingMethods( + valueSelectionParameters, + method.getOptions().getMapMapping().getValueMappingControl( ctx.getElementUtils() ), + null, + false ); + Assignment valueAssignment = ctx.getMappingResolver().getTargetAssignment( method, + getDescription(), valueTargetType, - null, // there is no targetPropertyName valueFormattingParameters, - valueSelectionParameters, + valueCriteria, valueSourceRHS, - false + null, + () -> forge( valueSourceRHS, valueSourceType, valueTargetType, Message.MAPMAPPING_CREATE_VALUE_NOTE ) ); if ( method instanceof ForgedMethod ) { @@ -159,10 +158,6 @@ public MapMappingMethod build() { } } - if ( valueAssignment == null ) { - valueAssignment = forgeMapping( valueSourceRHS, valueSourceType, valueTargetType ); - } - if ( valueAssignment == null ) { if ( method instanceof ForgedMethod ) { // leave messaging to calling property mapping @@ -174,7 +169,7 @@ public MapMappingMethod build() { String.format( "%s \"%s\"", valueSourceRHS.getSourceErrorMessagePart(), - valueSourceRHS.getSourceType() + valueSourceRHS.getSourceType().describe() ), valueSourceRHS.getSourceType(), valueTargetType, @@ -182,65 +177,105 @@ public MapMappingMethod build() { ); } } + else { + ctx.getMessager().note( 2, Message.MAPMAPPING_SELECT_VALUE_NOTE, valueAssignment ); + } - // mapNullToDefault - boolean mapNullToDefault = false; - if ( method.getMapperConfiguration() != null ) { - mapNullToDefault = method.getMapperConfiguration().isMapToDefault( nullValueMappingStrategy ); + // mapNullToDefault — a JSpecify @NonNull return forces RETURN_DEFAULT to avoid generating `return null`. + // Forcing is unconditional here (unlike BeanMappingMethod): when the source is @NonNull the template skips + // the whole guard block via `sourceParameterPresenceCheck??`, so the forced value is simply unused there. + boolean mapNullToDefault = + method.getOptions().getMapMapping().getNullValueMappingStrategy().isReturnDefault(); + if ( !mapNullToDefault && ctx.isJSpecifyNonNullReturn( method ) ) { + ctx.getMessager().note( 2, + Message.MAPPING_METHOD_JSPECIFY_FORCE_RETURN_DEFAULT, + method.getName() ); + mapNullToDefault = true; } MethodReference factoryMethod = null; if ( !method.isUpdateMethod() ) { factoryMethod = ObjectFactoryMethodResolver - .getFactoryMethod( method, method.getResultType(), null, ctx ); + .getFactoryMethod( method, null, ctx ); } keyAssignment = new LocalVarWrapper( keyAssignment, method.getThrownTypes(), keyTargetType, false ); valueAssignment = new LocalVarWrapper( valueAssignment, method.getThrownTypes(), valueTargetType, false ); - Set existingVariables = new HashSet( method.getParameterNames() ); + Set existingVariables = new HashSet<>( method.getParameterNames() ); List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( method, null, ctx, existingVariables ); List afterMappingMethods = LifecycleMethodResolver.afterMappingMethods( method, null, ctx, existingVariables ); + Parameter sourceParam = first( method.getSourceParameters() ); + PresenceCheck sourceParameterPresenceCheck = + PresenceCheckMethodResolver.getPresenceCheckForSourceParameter( method, null, sourceParam, ctx ); + return new MapMappingMethod( method, + getMethodAnnotations(), existingVariables, keyAssignment, valueAssignment, factoryMethod, mapNullToDefault, beforeMappingMethods, - afterMappingMethods + afterMappingMethods, + sourceParameterPresenceCheck ); } + Assignment forge(SourceRHS sourceRHS, Type sourceType, Type targetType, Message message ) { + Assignment assignment = forgeMapping( sourceRHS, sourceType, targetType ); + if ( assignment != null ) { + ctx.getMessager().note( 2, message, assignment ); + } + return assignment; + } + @Override protected boolean shouldUsePropertyNamesInHistory() { return true; } + } - private MapMappingMethod(Method method, Collection existingVariableNames, Assignment keyAssignment, + //CHECKSTYLE:OFF + private MapMappingMethod(Method method, List annotations, + Collection existingVariableNames, Assignment keyAssignment, Assignment valueAssignment, MethodReference factoryMethod, boolean mapNullToDefault, List beforeMappingReferences, - List afterMappingReferences) { - super( method, existingVariableNames, factoryMethod, mapNullToDefault, beforeMappingReferences, + List afterMappingReferences, + PresenceCheck sourceParameterPresenceCheck) { + //CHECKSTYLE:ON + super( method, annotations, existingVariableNames, factoryMethod, mapNullToDefault, beforeMappingReferences, afterMappingReferences ); this.keyAssignment = keyAssignment; this.valueAssignment = valueAssignment; - } - - public Parameter getSourceParameter() { + Parameter sourceParameter = null; for ( Parameter parameter : getParameters() ) { if ( !parameter.isMappingTarget() && !parameter.isMappingContext() ) { - return parameter; + sourceParameter = parameter; + break; } } - throw new IllegalStateException( "Method " + this + " has no source parameter." ); + if ( sourceParameter == null ) { + throw new IllegalStateException( "Method " + this + " has no source parameter." ); + } + + this.sourceParameter = sourceParameter; + this.sourceParameterPresenceCheck = sourceParameterPresenceCheck; + } + + public Parameter getSourceParameter() { + return sourceParameter; + } + + public PresenceCheck getSourceParameterPresenceCheck() { + return sourceParameterPresenceCheck; } public List getSourceElementTypes() { @@ -279,21 +314,21 @@ public Set getImportTypes() { } public String getKeyVariableName() { - return Strings.getSaveVariableName( + return Strings.getSafeVariableName( "key", getParameterNames() ); } public String getValueVariableName() { - return Strings.getSaveVariableName( + return Strings.getSafeVariableName( "value", getParameterNames() ); } public String getEntryVariableName() { - return Strings.getSaveVariableName( + return Strings.getSafeVariableName( "entry", getParameterNames() ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java index efe8e49d01..c261358455 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/Mapper.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.List; +import java.util.Set; import java.util.SortedSet; - import javax.lang.model.element.Element; -import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.Type; @@ -32,6 +17,8 @@ import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.version.VersionInformation; +import static org.mapstruct.ap.internal.gem.ClassAccessibilityGem.DEFAULT; + /** * Represents a type implementing a mapper interface (annotated with {@code @Mapper}). This is the root object of the * mapper model. @@ -45,89 +32,42 @@ public class Mapper extends GeneratedType { static final String DEFAULT_IMPLEMENTATION_CLASS = CLASS_NAME_PLACEHOLDER + "Impl"; static final String DEFAULT_IMPLEMENTATION_PACKAGE = PACKAGE_NAME_PLACEHOLDER; - private final boolean customPackage; - private final boolean customImplName; - private final List referencedMappers; - private Decorator decorator; - - @SuppressWarnings( "checkstyle:parameternumber" ) - private Mapper(TypeFactory typeFactory, String packageName, String name, String superClassName, - String interfacePackage, String interfaceName, boolean customPackage, boolean customImplName, - List methods, Options options, VersionInformation versionInformation, - Accessibility accessibility, List referencedMappers, Decorator decorator, - SortedSet extraImportedTypes) { - - super( - typeFactory, - packageName, - name, - superClassName, - interfacePackage, - interfaceName, - methods, - referencedMappers, - options, - versionInformation, - accessibility, - extraImportedTypes, - null - ); - this.customPackage = customPackage; - this.customImplName = customImplName; - - this.referencedMappers = referencedMappers; - this.decorator = decorator; - } + public static class Builder extends GeneratedTypeBuilder { - public static class Builder { - - private TypeFactory typeFactory; private TypeElement element; - private List mappingMethods; - private List mapperReferences; - private SortedSet extraImportedTypes; + private List fields; + private Set fragments; - private Elements elementUtils; - private Options options; - private VersionInformation versionInformation; private Decorator decorator; private String implName; private boolean customName; private String implPackage; private boolean customPackage; + private boolean suppressGeneratorTimestamp; + private Set customAnnotations; + private Javadoc javadoc; - public Builder element(TypeElement element) { - this.element = element; - return this; - } - - public Builder mappingMethods(List mappingMethods) { - this.mappingMethods = mappingMethods; - return this; + public Builder() { + super( Builder.class ); } - public Builder mapperReferences(List mapperReferences) { - this.mapperReferences = mapperReferences; - return this; - } - - public Builder options(Options options) { - this.options = options; + public Builder element(TypeElement element) { + this.element = element; return this; } - public Builder versionInformation(VersionInformation versionInformation) { - this.versionInformation = versionInformation; + public Builder fields(List fields) { + this.fields = fields; return this; } - public Builder typeFactory(TypeFactory typeFactory) { - this.typeFactory = typeFactory; + public Builder constructorFragments(Set fragments) { + this.fragments = fragments; return this; } - public Builder elementUtils(Elements elementUtils) { - this.elementUtils = elementUtils; + public Builder additionalAnnotations(Set customAnnotations) { + this.customAnnotations = customAnnotations; return this; } @@ -136,11 +76,6 @@ public Builder decorator(Decorator decorator) { return this; } - public Builder extraImports(SortedSet extraImportedTypes) { - this.extraImportedTypes = extraImportedTypes; - return this; - } - public Builder implName(String implName) { this.implName = implName; this.customName = !DEFAULT_IMPLEMENTATION_CLASS.equals( this.implName ); @@ -153,35 +88,91 @@ public Builder implPackage(String implPackage) { return this; } + public Builder suppressGeneratorTimestamp(boolean suppressGeneratorTimestamp) { + this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; + return this; + } + + public Builder javadoc(Javadoc javadoc) { + this.javadoc = javadoc; + return this; + } + public Mapper build() { String implementationName = implName.replace( CLASS_NAME_PLACEHOLDER, getFlatName( element ) ) + - ( decorator == null ? "" : "_" ); + ( decorator == null ? "" : "_" ); String elementPackage = elementUtils.getPackageOf( element ).getQualifiedName().toString(); String packageName = implPackage.replace( PACKAGE_NAME_PLACEHOLDER, elementPackage ); + Constructor constructor = null; + if ( !fragments.isEmpty() ) { + constructor = new NoArgumentConstructor( implementationName, fragments ); + } + + Type definitionType = typeFactory.getType( element ); + + Accessibility accessibility = + classAccessibility == DEFAULT ? Accessibility.fromModifiers( element.getModifiers() ) : + Accessibility.valueOf( classAccessibility.name() ); return new Mapper( typeFactory, packageName, implementationName, - element.getKind() != ElementKind.INTERFACE ? element.getSimpleName().toString() : null, - elementPackage, - element.getKind() == ElementKind.INTERFACE ? element.getSimpleName().toString() : null, + definitionType, customPackage, customName, - mappingMethods, + customAnnotations, + methods, options, versionInformation, - Accessibility.fromModifiers( element.getModifiers() ), - mapperReferences, + suppressGeneratorTimestamp, + accessibility, + fields, + constructor, decorator, - extraImportedTypes + extraImportedTypes, + javadoc ); } + } - public List getReferencedMappers() { - return referencedMappers; + private final boolean customPackage; + private final boolean customImplName; + private Decorator decorator; + private final Javadoc javadoc; + + @SuppressWarnings( "checkstyle:parameternumber" ) + private Mapper(TypeFactory typeFactory, String packageName, String name, + Type mapperDefinitionType, + boolean customPackage, boolean customImplName, Set customAnnotations, + List methods, Options options, VersionInformation versionInformation, + boolean suppressGeneratorTimestamp, + Accessibility accessibility, List fields, Constructor constructor, + Decorator decorator, SortedSet extraImportedTypes, Javadoc javadoc ) { + + super( + typeFactory, + packageName, + name, + mapperDefinitionType, + methods, + fields, + options, + versionInformation, + suppressGeneratorTimestamp, + accessibility, + extraImportedTypes, + constructor + ); + this.customPackage = customPackage; + this.customImplName = customImplName; + customAnnotations.forEach( this::addAnnotation ); + + this.decorator = decorator; + + this.javadoc = javadoc; } public Decorator getDecorator() { @@ -196,6 +187,11 @@ public boolean hasCustomImplementation() { return customImplName || customPackage; } + @Override + public Javadoc getJavadoc() { + return javadoc; + } + @Override protected String getTemplateName() { return getTemplateNameForClass( GeneratedType.class ); @@ -203,14 +199,18 @@ protected String getTemplateName() { /** * Returns the same as {@link Class#getName()} but without the package declaration. + * + * @param element the element that should be flattened + * + * @return the flat name for the type element */ public static String getFlatName(TypeElement element) { - if (!(element.getEnclosingElement() instanceof TypeElement)) { + if ( !(element.getEnclosingElement() instanceof TypeElement) ) { return element.getSimpleName().toString(); } StringBuilder nameBuilder = new StringBuilder( element.getSimpleName().toString() ); - for (Element enclosing = element.getEnclosingElement(); enclosing instanceof TypeElement; enclosing = - enclosing.getEnclosingElement()) { + for ( Element enclosing = element.getEnclosingElement(); enclosing instanceof TypeElement; enclosing = + enclosing.getEnclosingElement() ) { nameBuilder.insert( 0, '$' ); nameBuilder.insert( 0, enclosing.getSimpleName().toString() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MapperReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MapperReference.java index 5fedcf285c..0179bd6324 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MapperReference.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MapperReference.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.List; + import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.SourceMethod; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java index fafce28fc5..39e8558e5e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingBuilderContext.java @@ -1,46 +1,39 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; - +import java.util.function.Supplier; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.model.source.ForgedMethod; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.model.source.SourceMethod; +import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.util.AccessorNamingUtils; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.NullabilityResolver; import org.mapstruct.ap.internal.util.Services; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.ap.internal.version.VersionInformation; +import org.mapstruct.ap.spi.EnumMappingStrategy; +import org.mapstruct.ap.spi.EnumTransformationStrategy; import org.mapstruct.ap.spi.MappingExclusionProvider; /** @@ -50,7 +43,7 @@ *

        *
      • Input for the building process, such as the source model (mapping methods found) and mapper references.
      • *
      • Required factory, utility, reporting methods for building the mappings.
      • - *
      • Means to harbor results produced by the builders, such as forged- and virtual mapping methods that should be + *
      • Means to harbor results produced by the builders, such as forged- and supported mapping methods that should be * generated in a later stage.
      • *
      * @@ -87,12 +80,13 @@ public interface MappingResolver { * returns a parameter assignment * * @param mappingMethod target mapping method + * @param description the description source * @param targetType return type to match - * @param targetPropertyName name of the target property * @param formattingParameters used for formatting dates and numbers - * @param selectionParameters parameters used in the selection process + * @param criteria parameters criteria in the selection process * @param sourceRHS source information - * @param preferUpdateMethods selection should prefer update methods when present. + * @param positionHint the mirror for reporting problems + * @param forger the supplier of the callback method to forge a method * * @return an assignment to a method parameter, which can either be: *
        @@ -102,33 +96,45 @@ public interface MappingResolver { *
      1. null, no assignment found
      2. *
      */ - Assignment getTargetAssignment(Method mappingMethod, Type targetType, String targetPropertyName, + Assignment getTargetAssignment(Method mappingMethod, ForgedMethodHistory description, Type targetType, FormattingParameters formattingParameters, - SelectionParameters selectionParameters, SourceRHS sourceRHS, - boolean preferUpdateMethods); + SelectionCriteria criteria, SourceRHS sourceRHS, + AnnotationMirror positionHint, + Supplier forger); + + Set getUsedSupportedMappings(); - Set getUsedVirtualMappings(); + Set getUsedSupportedFields(); } private final TypeFactory typeFactory; - private final Elements elementUtils; - private final Types typeUtils; + private final ElementUtils elementUtils; + private final TypeUtils typeUtils; private final FormattingMessager messager; + private final VersionInformation versionInformation; private final AccessorNamingUtils accessorNaming; + private final NullabilityResolver nullabilityResolver; + private final EnumMappingStrategy enumMappingStrategy; + private final Map enumTransformationStrategies; private final Options options; private final TypeElement mapperTypeElement; private final List sourceModel; private final List mapperReferences; private final MappingResolver mappingResolver; - private final List mappingsToGenerate = new ArrayList(); + private final List mappingsToGenerate = new ArrayList<>(); private final Map forgedMethodsUnderCreation = - new HashMap( ); + new HashMap<>(); + //CHECKSTYLE:OFF public MappingBuilderContext(TypeFactory typeFactory, - Elements elementUtils, - Types typeUtils, + ElementUtils elementUtils, + TypeUtils typeUtils, FormattingMessager messager, + VersionInformation versionInformation, AccessorNamingUtils accessorNaming, + NullabilityResolver nullabilityResolver, + EnumMappingStrategy enumMappingStrategy, + Map enumTransformationStrategies, Options options, MappingResolver mappingResolver, TypeElement mapper, @@ -138,13 +144,18 @@ public MappingBuilderContext(TypeFactory typeFactory, this.elementUtils = elementUtils; this.typeUtils = typeUtils; this.messager = messager; + this.versionInformation = versionInformation; this.accessorNaming = accessorNaming; + this.nullabilityResolver = nullabilityResolver; + this.enumMappingStrategy = enumMappingStrategy; + this.enumTransformationStrategies = enumTransformationStrategies; this.options = options; this.mappingResolver = mappingResolver; this.mapperTypeElement = mapper; this.sourceModel = sourceModel; this.mapperReferences = mapperReferences; } + //CHECKSTYLE:ON /** * Returns a map which is used to track which forged methods are under creation. @@ -175,11 +186,11 @@ public TypeFactory getTypeFactory() { return typeFactory; } - public Elements getElementUtils() { + public ElementUtils getElementUtils() { return elementUtils; } - public Types getTypeUtils() { + public TypeUtils getTypeUtils() { return typeUtils; } @@ -187,10 +198,60 @@ public FormattingMessager getMessager() { return messager; } + public VersionInformation getVersionInformation() { + return versionInformation; + } + public AccessorNamingUtils getAccessorNaming() { return accessorNaming; } + public NullabilityResolver getNullabilityResolver() { + return nullabilityResolver; + } + + /** + * Resolves the JSpecify nullability of an element declared directly on the mapper (e.g. a mapping method's + * return type or one of its source parameters), using the mapper type's {@code @NullMarked} scope as the + * enclosing scope for unannotated elements. + * + * @param element the element declared on the mapper to inspect + * + * @return the resolved nullability ({@link NullabilityResolver.Nullability#UNKNOWN} when JSpecify is disabled) + */ + public NullabilityResolver.Nullability getNullabilityInMapperScope(Element element) { + return nullabilityResolver.getNullability( + element, + () -> typeFactory.getType( mapperTypeElement.asType() ).isNullMarked() ); + } + + /** + * Whether the return type of the given mapping method is JSpecify {@code @NonNull} (directly or via a + * {@code @NullMarked} scope). When it is, a mapping method must not generate {@code return null}, so callers + * force {@link org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem#RETURN_DEFAULT} semantics. + *

      + * Update methods and {@code void}-returning methods never generate a {@code return null} and are excluded. + * + * @param method the mapping method to inspect + * + * @return {@code true} if the return type is {@code @NonNull}, {@code false} otherwise + */ + public boolean isJSpecifyNonNullReturn(Method method) { + if ( method.isUpdateMethod() || method.getReturnType().isVoid() ) { + return false; + } + + return getNullabilityInMapperScope( method.getExecutable() ) == NullabilityResolver.Nullability.NON_NULL; + } + + public EnumMappingStrategy getEnumMappingStrategy() { + return enumMappingStrategy; + } + + public Map getEnumTransformationStrategies() { + return enumTransformationStrategies; + } + public Options getOptions() { return options; } @@ -203,12 +264,18 @@ public List getMappingsToGenerate() { return mappingsToGenerate; } - public List getNamesOfMappingsToGenerate() { - List nameList = new ArrayList(); + public List getReservedNames() { + Set nameSet = new HashSet<>(); for ( MappingMethod method : mappingsToGenerate ) { - nameList.add( method.getName() ); + nameSet.add( method.getName() ); + } + // add existing names + for ( SourceMethod method : sourceModel ) { + if ( method.isAbstract() ) { + nameSet.add( method.getName() ); + } } - return nameList; + return new ArrayList<>( nameSet ); } public MappingMethod getExistingMappingMethod(MappingMethod newMappingMethod) { @@ -222,8 +289,12 @@ public MappingMethod getExistingMappingMethod(MappingMethod newMappingMethod) { return existingMappingMethod; } - public Set getUsedVirtualMappings() { - return mappingResolver.getUsedVirtualMappings(); + public Set getUsedSupportedMappings() { + return mappingResolver.getUsedSupportedMappings(); + } + + public Set getUsedSupportedFields() { + return mappingResolver.getUsedSupportedFields(); } /** @@ -238,11 +309,18 @@ public boolean canGenerateAutoSubMappingBetween(Type sourceType, Type targetType } /** - * @param type that MapStruct wants to use to genrate an autoamtic sub-mapping for/from + * @param type that MapStruct wants to use to generate an automatic sub-mapping for/from * * @return {@code true} if the type is not excluded from the {@link MappingExclusionProvider} */ private boolean canGenerateAutoSubMappingFor(Type type) { + if ( "java.util.Optional".equals( type.getFullyQualifiedName() ) ) { + return !SUB_MAPPING_EXCLUSION_PROVIDER.isExcluded( type.getOptionalBaseType().getTypeElement() ); + } return type.getTypeElement() != null && !SUB_MAPPING_EXCLUSION_PROVIDER.isExcluded( type.getTypeElement() ); } + + public boolean isErroneous() { + return messager.isErroneous(); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java index 0f80ddd11c..0d04f5b6d5 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MappingMethod.java @@ -1,44 +1,32 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Strings.getSaveVariableName; -import static org.mapstruct.ap.internal.util.Strings.join; - import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import org.mapstruct.ap.internal.model.common.Accessibility; -import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; +import static org.mapstruct.ap.internal.util.Strings.getSafeVariableName; +import static org.mapstruct.ap.internal.util.Strings.join; + /** * A method implemented or referenced by a {@link Mapper} class. * * @author Gunnar Morling */ -public abstract class MappingMethod extends ModelElement { +public abstract class MappingMethod extends GeneratedTypeMethod { private final String name; private final List parameters; @@ -82,20 +70,20 @@ protected MappingMethod(Method method, List parameters, Collection parameters) { - this( method, parameters, new ArrayList( method.getParameterNames() ), null, null ); + this( method, parameters, new ArrayList<>( method.getParameterNames() ), null, null ); } protected MappingMethod(Method method) { - this( method, new ArrayList( method.getParameterNames() ), null, null ); + this( method, new ArrayList<>( method.getParameterNames() ), null, null ); } protected MappingMethod(Method method, List beforeMappingReferences, List afterMappingReferences) { - this( method, new ArrayList( method.getParameterNames() ), beforeMappingReferences, + this( method, new ArrayList<>( method.getParameterNames() ), beforeMappingReferences, afterMappingReferences ); } @@ -104,12 +92,16 @@ private String initResultName(Collection existingVarNames) { return targetParameter.getName(); } else if ( getResultType().isArrayType() ) { - String name = getSaveVariableName( getResultType().getComponentType().getName() + "Tmp", existingVarNames ); + String name = getSafeVariableName( getResultType().getComponentType().getName() + "Tmp", existingVarNames ); existingVarNames.add( name ); return name; } else { - String name = getSaveVariableName( getResultType().getName(), existingVarNames ); + Type resultType = getResultType(); + if ( resultType.isOptionalType() ) { + resultType = resultType.getOptionalBaseType(); + } + String name = getSafeVariableName( resultType.getName(), existingVarNames ); existingVarNames.add( name ); return name; } @@ -153,7 +145,7 @@ public boolean isStatic() { @Override public Set getImportTypes() { - Set types = new HashSet(); + Set types = new HashSet<>(); for ( Parameter param : parameters ) { types.addAll( param.getType().getImportTypes() ); @@ -165,11 +157,21 @@ public Set getImportTypes() { types.addAll( type.getImportTypes() ); } + for ( LifecycleCallbackMethodReference reference : beforeMappingReferencesWithMappingTarget ) { + types.addAll( reference.getImportTypes() ); + } + for ( LifecycleCallbackMethodReference reference : beforeMappingReferencesWithoutMappingTarget ) { + types.addAll( reference.getImportTypes() ); + } + for ( LifecycleCallbackMethodReference reference : afterMappingReferences ) { + types.addAll( reference.getImportTypes() ); + } + return types; } protected List getParameterNames() { - List parameterNames = new ArrayList( parameters.size() ); + List parameterNames = new ArrayList<>( parameters.size() ); for ( Parameter parameter : parameters ) { parameterNames.add( parameter.getName() ); @@ -187,14 +189,14 @@ public String toString() { return returnType + " " + getName() + "(" + join( parameters, ", " ) + ")"; } - private List filterMappingTarget(List methods, - boolean mustHaveMappingTargetParameter) { + protected static List filterMappingTarget( + List methods, boolean mustHaveMappingTargetParameter) { if ( methods == null ) { - return null; + return Collections.emptyList(); } List result = - new ArrayList( methods.size() ); + new ArrayList<>( methods.size() ); for ( LifecycleCallbackMethodReference method : methods ) { if ( mustHaveMappingTargetParameter == method.hasMappingTargetParameter() ) { @@ -240,15 +242,15 @@ public boolean equals(Object obj) { //Reason: Whenever we forge methods we can reuse mappings if they are the same. However, if we take the name // into consideration, they'll never be the same, because we create safe methods names. final MappingMethod other = (MappingMethod) obj; - if ( this.parameters != other.parameters && - (this.parameters == null || !this.parameters.equals( other.parameters )) ) { + + if ( !Objects.equals( parameters, other.parameters ) ) { return false; } - if ( this.returnType != other.returnType && - (this.returnType == null || !this.returnType.equals( other.returnType )) ) { + + if ( !Objects.equals( returnType, other.returnType ) ) { return false; } + return true; } - } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReference.java index 003c196ab0..e2e518c55b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReference.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReference.java @@ -1,37 +1,30 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Objects; import java.util.Set; +import java.util.stream.Collectors; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.ParameterBinding; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod; +import org.mapstruct.ap.internal.util.Strings; /** * Represents a reference to another method, e.g. used to map a bean property from source to target type or to @@ -66,7 +59,10 @@ public class MethodReference extends ModelElement implements Assignment { private final Type definingType; private final List parameterBindings; private final Parameter providingParameter; + private final List methodsToChain; private final boolean isStatic; + private final boolean isConstructor; + private final boolean isMethodChaining; /** * Creates a new reference to the given method. @@ -85,7 +81,7 @@ protected MethodReference(Method method, MapperReference declaringMapper, Parame this.providingParameter = providingParameter; this.parameterBindings = parameterBindings; this.contextParam = null; - Set imported = new HashSet(); + Set imported = new HashSet<>(); for ( Type type : method.getThrownTypes() ) { imported.addAll( type.getImportTypes() ); @@ -95,12 +91,15 @@ protected MethodReference(Method method, MapperReference declaringMapper, Parame imported.addAll( binding.getImportTypes() ); } - this.importTypes = Collections.unmodifiableSet( imported ); + this.importTypes = Collections.unmodifiableSet( imported ); this.thrownTypes = method.getThrownTypes(); this.isUpdateMethod = method.getMappingTargetParameter() != null; this.definingType = method.getDefiningType(); this.isStatic = method.isStatic(); this.name = method.getName(); + this.isConstructor = false; + this.methodsToChain = Collections.emptyList(); + this.isMethodChaining = false; } private MethodReference(BuiltInMethod method, ConversionContext contextParam) { @@ -116,6 +115,9 @@ private MethodReference(BuiltInMethod method, ConversionContext contextParam) { this.parameterBindings = ParameterBinding.fromParameters( method.getParameters() ); this.isStatic = method.isStatic(); this.name = method.getName(); + this.isConstructor = false; + this.methodsToChain = Collections.emptyList(); + this.isMethodChaining = false; } private MethodReference(String name, Type definingType, boolean isStatic) { @@ -131,6 +133,59 @@ private MethodReference(String name, Type definingType, boolean isStatic) { this.parameterBindings = Collections.emptyList(); this.providingParameter = null; this.isStatic = isStatic; + this.isConstructor = false; + this.methodsToChain = Collections.emptyList(); + this.isMethodChaining = false; + } + + private MethodReference(Type definingType, List parameterBindings) { + this.name = null; + this.definingType = definingType; + this.sourceParameters = Collections.emptyList(); + this.returnType = null; + this.declaringMapper = null; + this.thrownTypes = Collections.emptyList(); + this.isUpdateMethod = false; + this.contextParam = null; + this.parameterBindings = parameterBindings; + this.providingParameter = null; + this.isStatic = false; + this.isConstructor = true; + this.methodsToChain = Collections.emptyList(); + this.isMethodChaining = false; + + if ( parameterBindings.isEmpty() ) { + this.importTypes = Collections.emptySet(); + } + else { + Set imported = new LinkedHashSet<>(); + + for ( ParameterBinding binding : parameterBindings ) { + imported.add( binding.getType() ); + } + + imported.add( definingType ); + + this.importTypes = Collections.unmodifiableSet( imported ); + } + } + + private MethodReference(MethodReference... references) { + this.name = null; + this.definingType = null; + this.sourceParameters = Collections.emptyList(); + this.returnType = null; + this.declaringMapper = null; + this.importTypes = Collections.emptySet(); + this.thrownTypes = Collections.emptyList(); + this.isUpdateMethod = false; + this.contextParam = null; + this.parameterBindings = null; + this.providingParameter = null; + this.isStatic = false; + this.isConstructor = false; + this.methodsToChain = Arrays.asList( references ); + this.isMethodChaining = true; } public MapperReference getDeclaringMapper() { @@ -168,11 +223,11 @@ public void setAssignment( Assignment assignment ) { @Override public String getSourceReference() { - return assignment.getSourceReference(); + return assignment != null ? assignment.getSourceReference() : null; } @Override - public String getSourcePresenceCheckerReference() { + public PresenceCheck getSourcePresenceCheckerReference() { return assignment.getSourcePresenceCheckerReference(); } @@ -182,8 +237,8 @@ public Type getSourceType() { } @Override - public String createLocalVarName( String desiredName ) { - return assignment.createLocalVarName( desiredName ); + public String createUniqueVarName(String desiredName ) { + return assignment.createUniqueVarName( desiredName ); } @Override @@ -196,6 +251,16 @@ public void setSourceLocalVarName(String sourceLocalVarName) { assignment.setSourceLocalVarName( sourceLocalVarName ); } + @Override + public String getSourceLoopVarName() { + return assignment.getSourceLoopVarName(); + } + + @Override + public void setSourceLoopVarName(String sourceLoopVarName) { + assignment.setSourceLoopVarName( sourceLoopVarName ); + } + @Override public String getSourceParameterName() { return assignment.getSourceParameterName(); @@ -224,23 +289,34 @@ public Type getDefiningType() { @Override public Set getImportTypes() { - Set imported = new HashSet( importTypes ); + Set imported = new HashSet<>( importTypes ); if ( assignment != null ) { imported.addAll( assignment.getImportTypes() ); } if ( isStatic() ) { imported.add( definingType ); } + if ( isMethodChaining() ) { + for ( MethodReference methodToChain : methodsToChain ) { + imported.addAll( methodToChain.getImportTypes() ); + } + } + return imported; } @Override public List getThrownTypes() { - List exceptions = new ArrayList(); - exceptions.addAll( thrownTypes ); + List exceptions = new ArrayList<>( thrownTypes ); if ( assignment != null ) { exceptions.addAll( assignment.getThrownTypes() ); } + if ( isMethodChaining() ) { + for ( MethodReference methodToChain : methodsToChain ) { + exceptions.addAll( methodToChain.getThrownTypes() ); + } + + } return exceptions; } @@ -272,10 +348,31 @@ public boolean isStatic() { return isStatic; } + public boolean isConstructor() { + return isConstructor; + } + + public boolean isMethodChaining() { + return isMethodChaining; + } + + public List getMethodsToChain() { + return methodsToChain; + } + public List getParameterBindings() { return parameterBindings; } + public Type inferTypeWhenEnum( Type type ) { + if ( "java.lang.Enum".equals( type.getFullyQualifiedName() ) ) { + return type.getTypeParameters().get( 0 ); + } + else { + return type; + } + } + @Override public int hashCode() { final int prime = 31; @@ -297,22 +394,13 @@ public boolean equals(Object obj) { return false; } MethodReference other = (MethodReference) obj; - if ( declaringMapper == null ) { - if ( other.declaringMapper != null ) { - return false; - } - } - else if ( !declaringMapper.equals( other.declaringMapper ) ) { + if ( !Objects.equals( declaringMapper, other.declaringMapper ) ) { return false; } - if ( providingParameter == null ) { - if ( other.providingParameter != null ) { - return false; - } - } - else if ( !providingParameter.equals( other.providingParameter ) ) { + if ( !Objects.equals( providingParameter, other.providingParameter ) ) { return false; } + return true; } @@ -341,4 +429,25 @@ public static MethodReference forStaticBuilder(String builderCreationMethod, Typ public static MethodReference forMethodCall(String methodName) { return new MethodReference( methodName, null, false ); } + + public static MethodReference forConstructorInvocation(Type type, List parameterBindings) { + return new MethodReference( type, parameterBindings ); + } + + public static MethodReference forMethodChaining(MethodReference... references) { + return new MethodReference( references ); + } + + @Override + public String toString() { + String mapper = declaringMapper != null ? declaringMapper.getType().getName() : ""; + String argument = getAssignment() != null ? getAssignment().toString() : + ( getSourceReference() != null ? getSourceReference() : "" ); + String returnTypeAsString = returnType != null ? returnType.toString() : ""; + List arguments = sourceParameters.stream() + .map( p -> p.isMappingContext() || p.isMappingTarget() || p.isTargetType() ? p.getName() : argument ) + .collect( Collectors.toList() ); + + return returnTypeAsString + " " + mapper + "#" + name + "(" + Strings.join( arguments, "," ) + ")"; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReferencePresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReferencePresenceCheck.java new file mode 100644 index 0000000000..29904ff416 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/MethodReferencePresenceCheck.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A {@link PresenceCheck} that is based on a {@link MethodReference}. + * + * @author Filip Hrisafov + */ +public class MethodReferencePresenceCheck extends ModelElement implements PresenceCheck { + + protected final MethodReference methodReference; + protected final boolean negate; + + public MethodReferencePresenceCheck(MethodReference methodReference) { + this( methodReference, false ); + } + + public MethodReferencePresenceCheck(MethodReference methodReference, boolean negate) { + this.methodReference = methodReference; + this.negate = negate; + } + + @Override + public Set getImportTypes() { + return methodReference.getImportTypes(); + } + + public MethodReference getMethodReference() { + return methodReference; + } + + public boolean isNegate() { + return negate; + } + + @Override + public PresenceCheck negate() { + return new MethodReferencePresenceCheck( methodReference, true ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + MethodReferencePresenceCheck that = (MethodReferencePresenceCheck) o; + return Objects.equals( methodReference, that.methodReference ); + } + + @Override + public int hashCode() { + return Objects.hash( methodReference ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.java index 973761f7c7..79341b8921 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.java @@ -1,33 +1,27 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; import java.util.Set; +import org.mapstruct.ap.internal.model.beanmapping.PropertyEntry; import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.PropertyEntry; +import org.mapstruct.ap.internal.model.presence.AnyPresenceChecksPresenceCheck; +import org.mapstruct.ap.internal.model.presence.NullPresenceCheck; +import org.mapstruct.ap.internal.model.presence.OptionalPresenceCheck; +import org.mapstruct.ap.internal.model.presence.SuffixPresenceCheck; +import org.mapstruct.ap.internal.util.NullabilityResolver; import org.mapstruct.ap.internal.util.Strings; -import org.mapstruct.ap.internal.util.ValueProvider; +import org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor; /** * This method is used to convert the nested properties as listed in propertyEntries into a method @@ -64,22 +58,112 @@ public Builder mappingContext(MappingBuilderContext mappingContext) { } public NestedPropertyMappingMethod build() { - List existingVariableNames = new ArrayList(); + List existingVariableNames = new ArrayList<>(); + Parameter sourceParameter = null; for ( Parameter parameter : method.getSourceParameters() ) { existingVariableNames.add( parameter.getName() ); + if ( sourceParameter == null && !parameter.isMappingTarget() && !parameter.isMappingContext() ) { + sourceParameter = parameter; + } } - final List thrownTypes = new ArrayList(); - List safePropertyEntries = new ArrayList(); - for ( PropertyEntry propertyEntry : propertyEntries ) { - String safeName = Strings.getSaveVariableName( propertyEntry.getName(), existingVariableNames ); - safePropertyEntries.add( new SafePropertyEntry( propertyEntry, safeName ) ); + final List thrownTypes = new ArrayList<>(); + List safePropertyEntries = new ArrayList<>(); + if ( sourceParameter == null ) { + throw new IllegalStateException( "Method " + method + " has no source parameter." ); + } + + String previousPropertyName = sourceParameter.getName(); + Type previousPropertyType = sourceParameter.getType(); + boolean previousEntryIsNonNull = false; + for ( int i = 0; i < propertyEntries.size(); i++ ) { + PropertyEntry propertyEntry = propertyEntries.get( i ); + PresenceCheck presenceCheck; + boolean currentEntryIsNonNull = ctx.getNullabilityResolver().getNullability( + propertyEntry.getReadAccessor().getElement(), + previousPropertyType::isNullMarked + ) == NullabilityResolver.Nullability.NON_NULL; + + if ( previousPropertyType.isOptionalType() ) { + String optionalValueSafeName = Strings.getSafeVariableName( + previousPropertyName + "Value", + existingVariableNames + ); + existingVariableNames.add( optionalValueSafeName ); + + presenceCheck = getPresenceCheck( propertyEntry, optionalValueSafeName ); + + String optionalValueSource = previousPropertyName + ".get()"; + boolean doesNotNeedFollowUpProperty = false; + if ( i == propertyEntries.size() - 1 ) { + // If this is the last property, and we do not have a presence check, + // then we do not need to assign the optional value + // e.g., we need to generate .get().getXxx(); + doesNotNeedFollowUpProperty = presenceCheck == null; + if ( doesNotNeedFollowUpProperty ) { + optionalValueSource += "." + propertyEntry.getReadAccessor().getReadValueSource(); + } + } + Type optionalBaseType = previousPropertyType.getOptionalBaseType(); + safePropertyEntries.add( new SafePropertyEntry( + optionalBaseType, + optionalValueSafeName, + optionalValueSource, + new OptionalPresenceCheck( previousPropertyName, ctx.getVersionInformation(), true ) + ) ); + if ( doesNotNeedFollowUpProperty ) { + break; + } + previousPropertyName = optionalValueSafeName; + + } + else { + presenceCheck = getPresenceCheck( propertyEntry, previousPropertyName ); + if ( i > 0 && !previousEntryIsNonNull ) { + // If this is not the first property entry, + // then we need to combine the presence check with a null check of the previous property. + // JSpecify: the null check is skipped when the previous accessor returns @NonNull. + if ( presenceCheck != null ) { + presenceCheck = new AnyPresenceChecksPresenceCheck( Arrays.asList( + new NullPresenceCheck( previousPropertyName, true ), + presenceCheck + ) ); + } + else { + presenceCheck = new NullPresenceCheck( previousPropertyName, true ); + } + } + } + + String safeName = Strings.getSafeVariableName( propertyEntry.getName(), existingVariableNames ); + String source = previousPropertyName + "." + propertyEntry.getReadAccessor().getReadValueSource(); + safePropertyEntries.add( new SafePropertyEntry( + propertyEntry.getType(), + safeName, + source, + presenceCheck + ) ); existingVariableNames.add( safeName ); thrownTypes.addAll( ctx.getTypeFactory().getThrownTypes( propertyEntry.getReadAccessor() ) ); + previousPropertyName = safeName; + previousPropertyType = propertyEntry.getType(); + previousEntryIsNonNull = currentEntryIsNonNull; } method.addThrownTypes( thrownTypes ); return new NestedPropertyMappingMethod( method, safePropertyEntries ); } + + private PresenceCheck getPresenceCheck(PropertyEntry propertyEntry, String previousPropertyName) { + PresenceCheckAccessor propertyPresenceChecker = propertyEntry.getPresenceChecker(); + if ( propertyPresenceChecker != null ) { + return new SuffixPresenceCheck( + previousPropertyName, + propertyPresenceChecker.getPresenceCheckSuffix(), + true + ); + } + return null; + } } private NestedPropertyMappingMethod( ForgedMethod method, List sourcePropertyEntries ) { @@ -103,8 +187,11 @@ public List getPropertyEntries() { @Override public Set getImportTypes() { Set types = super.getImportTypes(); - for ( SafePropertyEntry propertyEntry : safePropertyEntries) { - types.add( propertyEntry.getType() ); + for ( SafePropertyEntry propertyEntry : safePropertyEntries ) { + types.addAll( propertyEntry.getType().getImportTypes() ); + if ( propertyEntry.getPresenceChecker() != null ) { + types.addAll( propertyEntry.getPresenceChecker().getImportTypes() ); + } } return types; } @@ -155,32 +242,27 @@ public boolean equals( Object obj ) { public static class SafePropertyEntry { private final String safeName; - private final String readAccessorName; - private final String presenceCheckerName; + private final String source; + private final PresenceCheck presenceChecker; private final Type type; - public SafePropertyEntry(PropertyEntry entry, String safeName) { + public SafePropertyEntry(Type type, String safeName, String source, PresenceCheck presenceCheck) { this.safeName = safeName; - this.readAccessorName = ValueProvider.of( entry.getReadAccessor() ).getValue(); - if ( entry.getPresenceChecker() != null ) { - this.presenceCheckerName = entry.getPresenceChecker().getSimpleName().toString(); - } - else { - this.presenceCheckerName = null; - } - this.type = entry.getType(); + this.source = source; + this.presenceChecker = presenceCheck; + this.type = type; } public String getName() { return safeName; } - public String getAccessorName() { - return readAccessorName; + public String getSource() { + return source; } - public String getPresenceCheckerName() { - return presenceCheckerName; + public PresenceCheck getPresenceChecker() { + return presenceChecker; } public Type getType() { @@ -198,26 +280,25 @@ public boolean equals(Object o) { SafePropertyEntry that = (SafePropertyEntry) o; - if ( readAccessorName != null ? !readAccessorName.equals( that.readAccessorName ) : - that.readAccessorName != null ) { + if ( !Objects.equals( source, that.source ) ) { return false; } - if ( presenceCheckerName != null ? !presenceCheckerName.equals( that.presenceCheckerName ) : - that.presenceCheckerName != null ) { + if ( !Objects.equals( presenceChecker, that.presenceChecker ) ) { return false; } - if ( type != null ? !type.equals( that.type ) : that.type != null ) { + if ( !Objects.equals( type, that.type ) ) { return false; } + return true; } @Override public int hashCode() { - int result = readAccessorName != null ? readAccessorName.hashCode() : 0; - result = 31 * result + ( presenceCheckerName != null ? presenceCheckerName.hashCode() : 0 ); + int result = source != null ? source.hashCode() : 0; + result = 31 * result + ( presenceChecker != null ? presenceChecker.hashCode() : 0 ); result = 31 * result + ( type != null ? type.hashCode() : 0 ); return result; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/NestedTargetPropertyMappingHolder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/NestedTargetPropertyMappingHolder.java index 7dd3ca680a..83464967e6 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/NestedTargetPropertyMappingHolder.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/NestedTargetPropertyMappingHolder.java @@ -1,39 +1,33 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Function; +import org.mapstruct.ap.internal.model.beanmapping.MappingReference; +import org.mapstruct.ap.internal.model.beanmapping.MappingReferences; +import org.mapstruct.ap.internal.model.beanmapping.PropertyEntry; +import org.mapstruct.ap.internal.model.beanmapping.SourceReference; +import org.mapstruct.ap.internal.model.beanmapping.TargetReference; import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.source.Mapping; +import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.MappingOptions; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.model.source.PropertyEntry; -import org.mapstruct.ap.internal.model.source.SourceReference; -import org.mapstruct.ap.internal.model.source.TargetReference; -import org.mapstruct.ap.internal.util.Extractor; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.accessor.Accessor; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; import static org.mapstruct.ap.internal.util.Collections.first; @@ -45,33 +39,16 @@ */ public class NestedTargetPropertyMappingHolder { - private static final Extractor SOURCE_PARAM_EXTRACTOR = new - Extractor() { - @Override - public Parameter apply(SourceReference sourceReference) { - return sourceReference.getParameter(); - } - }; - - private static final Extractor PROPERTY_EXTRACTOR = new - Extractor() { - @Override - public PropertyEntry apply(SourceReference sourceReference) { - return sourceReference.getPropertyEntries().isEmpty() ? null : - first( sourceReference.getPropertyEntries() ); - } - }; - private final List processedSourceParameters; private final Set handledTargets; private final List propertyMappings; - private final Map> unprocessedDefinedTarget; + private final Map> unprocessedDefinedTarget; private final boolean errorOccurred; public NestedTargetPropertyMappingHolder( List processedSourceParameters, Set handledTargets, List propertyMappings, - Map> unprocessedDefinedTarget, boolean errorOccurred) { + Map> unprocessedDefinedTarget, boolean errorOccurred) { this.processedSourceParameters = processedSourceParameters; this.handledTargets = handledTargets; this.propertyMappings = propertyMappings; @@ -87,7 +64,7 @@ public List getProcessedSourceParameters() { } /** - * @return all the targets that were hanled + * @return all the targets that were handled */ public Set getHandledTargets() { return handledTargets; @@ -103,7 +80,7 @@ public List getPropertyMappings() { /** * @return a map of all the unprocessed defined targets that can be applied to name forged base methods */ - public Map> getUnprocessedDefinedTarget() { + public Map> getUnprocessedDefinedTarget() { return unprocessedDefinedTarget; } @@ -117,10 +94,19 @@ public boolean hasErrorOccurred() { public static class Builder { private Method method; + private MappingReferences mappingReferences; private MappingBuilderContext mappingContext; private Set existingVariableNames; private List propertyMappings; private Set handledTargets; + private Map targetPropertiesWriteAccessors; + private Type targetType; + private boolean errorOccurred; + + public Builder mappingReferences(MappingReferences mappingReferences) { + this.mappingReferences = mappingReferences; + return this; + } public Builder method(Method method) { this.method = method; @@ -137,31 +123,40 @@ public Builder existingVariableNames(Set existingVariableNames) { return this; } + public Builder targetPropertiesWriteAccessors(Map targetPropertiesWriteAccessors) { + this.targetPropertiesWriteAccessors = targetPropertiesWriteAccessors; + return this; + } + + public Builder targetPropertyType(Type targetType) { + this.targetType = targetType; + return this; + } + public NestedTargetPropertyMappingHolder build() { - List processedSourceParameters = new ArrayList(); - handledTargets = new HashSet(); - propertyMappings = new ArrayList(); + List processedSourceParameters = new ArrayList<>(); + handledTargets = new HashSet<>(); + propertyMappings = new ArrayList<>(); // first we group by the first property in the target properties and for each of those // properties we get the new mappings as if the first property did not exist. - GroupedTargetReferences groupedByTP = groupByTargetReferences( method.getMappingOptions() ); - Map> unprocessedDefinedTarget - = new LinkedHashMap>(); + GroupedTargetReferences groupedByTP = groupByTargetReferences( ); + Map> unprocessedDefinedTarget = new LinkedHashMap<>(); - for ( Map.Entry> entryByTP : groupedByTP.poppedTargetReferences.entrySet() ) { - PropertyEntry targetProperty = entryByTP.getKey(); + for ( Map.Entry> entryByTP : + groupedByTP.poppedTargetReferences.entrySet() ) { + String targetProperty = entryByTP.getKey(); //Now we are grouping the already popped mappings by the source parameter(s) of the method GroupedBySourceParameters groupedBySourceParam = groupBySourceParameter( entryByTP.getValue(), groupedByTP.singleTargetReferences.get( targetProperty ) ); - boolean multipleSourceParametersForTP = - groupedBySourceParam.groupedBySourceParameter.keySet().size() > 1; + boolean multipleSourceParametersForTP = groupedBySourceParam.groupedBySourceParameter.size() > 1; // All not processed mappings that should have been applied to all are part of the unprocessed // defined targets unprocessedDefinedTarget.put( targetProperty, groupedBySourceParam.notProcessedAppliesToAll ); - for ( Map.Entry> entryByParam : groupedBySourceParam + for ( Map.Entry> entryByParam : groupedBySourceParam .groupedBySourceParameter.entrySet() ) { Parameter sourceParameter = entryByParam.getKey(); @@ -173,16 +168,24 @@ public NestedTargetPropertyMappingHolder build() { groupedByTP.singleTargetReferences.get( targetProperty ) ); + // We need an update method in the when one of the following is satisfied: + // 1) Multiple source parameters for the target reference + // 2) Multiple source references for the target reference + // The reason for this is that multiple sources have effect on the target. + // See Issue1828Test for more info. + boolean forceUpdateMethod = + multipleSourceParametersForTP || groupedSourceReferences.groupedBySourceReferences.size() > 1; + + boolean forceUpdateMethodOrNonNestedReferencesPresent = + forceUpdateMethod || !groupedSourceReferences.nonNested.isEmpty(); // For all the groupedBySourceReferences we need to create property mappings // from the Mappings and not restrict on the defined mappings (allow to forge name based mapping) // if we have composite methods i.e. more then 2 parameters then we have to force a creation // of an update method in our generation - for ( Map.Entry> entryBySP : groupedSourceReferences + for ( Map.Entry> entryBySP : groupedSourceReferences .groupedBySourceReferences .entrySet() ) { PropertyEntry sourceEntry = entryBySP.getKey(); - boolean forceUpdateMethodOrNonNestedReferencesPresent = - multipleSourceParametersForTP || !groupedSourceReferences.nonNested.isEmpty(); // If there are multiple source parameters that are mapped to the target reference // then we restrict the mapping only to the defined mappings. And we create MappingOptions // for forged methods (which means that any unmapped target properties are ignored) @@ -192,24 +195,24 @@ public NestedTargetPropertyMappingHolder build() { // @Mapping(target = "vehicleInfo.images", source = "images") //}) // See Issue1269Test, Issue1247Test, AutomappingAndNestedTest for more info as well - MappingOptions sourceMappingOptions = MappingOptions.forMappingsOnly( - groupByTargetName( entryBySP.getValue() ), + MappingReferences sourceMappingRefs = new MappingReferences( entryBySP.getValue(), multipleSourceParametersForTP, forceUpdateMethodOrNonNestedReferencesPresent ); + SourceReference sourceRef = new SourceReference.BuilderFromProperty() .sourceParameter( sourceParameter ) .type( sourceEntry.getType() ) .readAccessor( sourceEntry.getReadAccessor() ) .presenceChecker( sourceEntry.getPresenceChecker() ) - .name( targetProperty.getName() ) + .name( targetProperty ) .build(); // If we have multiple source parameters that are mapped to the target reference, or // parts of the nested properties are mapped to different sources (see comment above as well) // we would force an update method PropertyMapping propertyMapping = createPropertyMappingForNestedTarget( - sourceMappingOptions, + sourceMappingRefs, targetProperty, sourceRef, forceUpdateMethodOrNonNestedReferencesPresent @@ -219,20 +222,18 @@ public NestedTargetPropertyMappingHolder build() { propertyMappings.add( propertyMapping ); } - handledTargets.add( entryByTP.getKey().getName() ); + handledTargets.add( entryByTP.getKey() ); } - // For the nonNested mappings (assymetric) Mappings we also forge mappings + // For the nonNested mappings (asymmetric) Mappings we also forge mappings // However, here we do not forge name based mappings and we only // do update on the defined Mappings. if ( !groupedSourceReferences.nonNested.isEmpty() ) { - MappingOptions nonNestedOptions = MappingOptions.forMappingsOnly( - groupByTargetName( groupedSourceReferences.nonNested ), - true - ); + MappingReferences mappingReferences = + new MappingReferences( groupedSourceReferences.nonNested, true ); SourceReference reference = new SourceReference.BuilderFromProperty() .sourceParameter( sourceParameter ) - .name( targetProperty.getName() ) + .name( targetProperty ) .build(); boolean forceUpdateMethodForNonNested = @@ -242,7 +243,7 @@ public NestedTargetPropertyMappingHolder build() { // an update method. The reason is that they might be for the same reference and we should // use update for it PropertyMapping propertyMapping = createPropertyMappingForNestedTarget( - nonNestedOptions, + mappingReferences, targetProperty, reference, forceUpdateMethodForNonNested @@ -252,7 +253,7 @@ public NestedTargetPropertyMappingHolder build() { propertyMappings.add( propertyMapping ); } - handledTargets.add( entryByTP.getKey().getName() ); + handledTargets.add( entryByTP.getKey() ); } handleSourceParameterMappings( @@ -271,7 +272,7 @@ public NestedTargetPropertyMappingHolder build() { handledTargets, propertyMappings, unprocessedDefinedTarget, - groupedByTP.errorOccurred + errorOccurred ); } @@ -283,22 +284,20 @@ public NestedTargetPropertyMappingHolder build() { * @param sourceParameter the source parameter that is used * @param forceUpdateMethod whether we need to force an update method */ - private void handleSourceParameterMappings(List sourceParameterMappings, PropertyEntry targetProperty, - Parameter sourceParameter, boolean forceUpdateMethod) { + private void handleSourceParameterMappings(Set sourceParameterMappings, + String targetProperty, Parameter sourceParameter, + boolean forceUpdateMethod) { if ( !sourceParameterMappings.isEmpty() ) { // The source parameter mappings have no mappings, the source name is actually the parameter itself - MappingOptions nonNestedOptions = MappingOptions.forMappingsOnly( - new HashMap>(), - false, - true - ); + MappingReferences nonNestedRefs = + new MappingReferences( Collections.emptySet(), false, true ); SourceReference reference = new SourceReference.BuilderFromProperty() .sourceParameter( sourceParameter ) - .name( targetProperty.getName() ) + .name( targetProperty ) .build(); PropertyMapping propertyMapping = createPropertyMappingForNestedTarget( - nonNestedOptions, + nonNestedRefs, targetProperty, reference, forceUpdateMethod @@ -308,13 +307,13 @@ private void handleSourceParameterMappings(List sourceParameterMappings propertyMappings.add( propertyMapping ); } - handledTargets.add( targetProperty.getName() ); + handledTargets.add( targetProperty ); } } /** - * The target references are popped. The {@code List<}{@link Mapping}{@code >} are keyed on the unique first - * entries of the target references. + * The target references are popped. The {@code List<}{@link MappingOptions}{@code >} are keyed on the unique + * first entries of the target references. * *

      *

      @@ -354,43 +353,34 @@ private void handleSourceParameterMappings(List sourceParameterMappings * } *

    * - * @param mappingOptions that need to be used to create the {@link GroupedTargetReferences} - * * @return See above */ - private GroupedTargetReferences groupByTargetReferences(MappingOptions mappingOptions) { - Map> mappings = mappingOptions.getMappings(); + private GroupedTargetReferences groupByTargetReferences( ) { // group all mappings based on the top level name before popping - Map> mappingsKeyedByProperty - = new LinkedHashMap>(); - Map> singleTargetReferences - = new LinkedHashMap>(); - boolean errorOccurred = false; - for ( List mapping : mappings.values() ) { - Mapping firstMapping = first( mapping ); - TargetReference targetReference = firstMapping.getTargetReference(); - if ( !targetReference.isValid() ) { - errorOccurred = true; + Map> mappingsKeyedByProperty = new LinkedHashMap<>(); + Map> singleTargetReferences = new LinkedHashMap<>(); + for ( MappingReference mapping : mappingReferences.getMappingReferences() ) { + TargetReference targetReference = mapping.getTargetReference(); + List propertyEntries = targetReference.getPropertyEntries(); + if ( propertyEntries.isEmpty() ) { + // This can happen if the target property is target = ".", + // this usually happens when doing a reverse mapping continue; } - PropertyEntry property = first( targetReference.getPropertyEntries() ); - Mapping newMapping = firstMapping.popTargetReference(); + String property = first( propertyEntries ); + MappingReference newMapping = mapping.popTargetReference(); if ( newMapping != null ) { // group properties on current name. - if ( !mappingsKeyedByProperty.containsKey( property ) ) { - mappingsKeyedByProperty.put( property, new ArrayList() ); - } - mappingsKeyedByProperty.get( property ).add( newMapping ); + mappingsKeyedByProperty.computeIfAbsent( property, propertyEntry -> new LinkedHashSet<>() ) + .add( newMapping ); } else { - if ( !singleTargetReferences.containsKey( property ) ) { - singleTargetReferences.put( property, new ArrayList() ); - } - singleTargetReferences.get( property ).add( firstMapping ); + singleTargetReferences.computeIfAbsent( property, propertyEntry -> new LinkedHashSet<>() ) + .add( mapping ); } } - return new GroupedTargetReferences( mappingsKeyedByProperty, singleTargetReferences, errorOccurred ); + return new GroupedTargetReferences( mappingsKeyedByProperty, singleTargetReferences ); } /** @@ -476,18 +466,16 @@ private GroupedTargetReferences groupByTargetReferences(MappingOptions mappingOp * property as the {@code mappings} * @return the split mapping options. */ - private GroupedBySourceParameters groupBySourceParameter(List mappings, - List singleTargetReferences) { + private GroupedBySourceParameters groupBySourceParameter(Set mappings, + Set singleTargetReferences) { - Map> mappingsKeyedByParameter = new LinkedHashMap>(); - List appliesToAll = new ArrayList(); - for ( Mapping mapping : mappings ) { + Map> mappingsKeyedByParameter = new LinkedHashMap<>(); + Set appliesToAll = new LinkedHashSet<>(); + for ( MappingReference mapping : mappings ) { if ( mapping.getSourceReference() != null && mapping.getSourceReference().isValid() ) { Parameter parameter = mapping.getSourceReference().getParameter(); - if ( !mappingsKeyedByParameter.containsKey( parameter ) ) { - mappingsKeyedByParameter.put( parameter, new ArrayList() ); - } - mappingsKeyedByParameter.get( parameter ).add( mapping ); + mappingsKeyedByParameter.computeIfAbsent( parameter, key -> new LinkedHashSet<>() ) + .add( mapping ); } else { appliesToAll.add( mapping ); @@ -497,15 +485,15 @@ private GroupedBySourceParameters groupBySourceParameter(List mappings, populateWithSingleTargetReferences( mappingsKeyedByParameter, singleTargetReferences, - SOURCE_PARAM_EXTRACTOR + SourceReference::getParameter ); - for ( Map.Entry> entry : mappingsKeyedByParameter.entrySet() ) { + for ( Map.Entry> entry : mappingsKeyedByParameter.entrySet() ) { entry.getValue().addAll( appliesToAll ); } - List notProcessAppliesToAll = - mappingsKeyedByParameter.isEmpty() ? appliesToAll : new ArrayList(); + Set notProcessAppliesToAll = + mappingsKeyedByParameter.isEmpty() ? appliesToAll : new LinkedHashSet<>(); return new GroupedBySourceParameters( mappingsKeyedByParameter, notProcessAppliesToAll ); } @@ -534,31 +522,29 @@ private GroupedBySourceParameters groupBySourceParameter(List mappings, * * * - * @param entryByParam the entry of a {@link Parameter} and it's associated {@link Mapping}(s) that need to - * be used for grouping on popped source references + * @param entryByParam the entry of a {@link Parameter} and it's associated {@link MappingOptions}(s) that need + * to be used for grouping on popped source references * @param singleTargetReferences the single target references that match the source mappings * * @return the Grouped Source References */ - private GroupedSourceReferences groupByPoppedSourceReferences(Map.Entry> entryByParam, - List singleTargetReferences) { - List mappings = entryByParam.getValue(); - List nonNested = new ArrayList(); - List appliesToAll = new ArrayList(); - List sourceParameterMappings = new ArrayList(); + private GroupedSourceReferences groupByPoppedSourceReferences( + Map.Entry> entryByParam, + Set singleTargetReferences) { + Set mappings = entryByParam.getValue(); + Set nonNested = new LinkedHashSet<>(); + Set appliesToAll = new LinkedHashSet<>(); + Set sourceParameterMappings = new LinkedHashSet<>(); // group all mappings based on the top level name before popping - Map> mappingsKeyedByProperty - = new LinkedHashMap>(); - for ( Mapping mapping : mappings ) { - - Mapping newMapping = mapping.popSourceReference(); + Map> mappingsKeyedByProperty + = new LinkedHashMap<>(); + for ( MappingReference mapping : mappings ) { + MappingReference newMapping = mapping.popSourceReference(); if ( newMapping != null ) { // group properties on current name. PropertyEntry property = first( mapping.getSourceReference().getPropertyEntries() ); - if ( !mappingsKeyedByProperty.containsKey( property ) ) { - mappingsKeyedByProperty.put( property, new ArrayList() ); - } - mappingsKeyedByProperty.get( property ).add( newMapping ); + mappingsKeyedByProperty.computeIfAbsent( property, propertyEntry -> new LinkedHashSet<>() ) + .add( newMapping ); } //This is an ignore, or some expression, or a default. We apply these to all else if ( mapping.getSourceReference() == null ) { @@ -574,7 +560,7 @@ else if ( mapping.getSourceReference() == null ) { // applied to everything. boolean hasNoMappings = mappingsKeyedByProperty.isEmpty() && nonNested.isEmpty(); Parameter sourceParameter = entryByParam.getKey(); - List singleTargetReferencesToUse = + Set singleTargetReferencesToUse = extractSingleTargetReferencesToUseAndPopulateSourceParameterMappings( singleTargetReferences, sourceParameterMappings, @@ -585,14 +571,15 @@ else if ( mapping.getSourceReference() == null ) { populateWithSingleTargetReferences( mappingsKeyedByProperty, singleTargetReferencesToUse, - PROPERTY_EXTRACTOR + sourceReference -> sourceReference.getPropertyEntries().isEmpty() ? null : + first( sourceReference.getPropertyEntries() ) ); - for ( Map.Entry> entry : mappingsKeyedByProperty.entrySet() ) { + for ( Map.Entry> entry : mappingsKeyedByProperty.entrySet() ) { entry.getValue().addAll( appliesToAll ); } - List notProcessedAppliesToAll = new ArrayList(); + Set notProcessedAppliesToAll = new LinkedHashSet<>(); // If the applied to all were not added to all properties because they were empty, and the non-nested // one are not empty, add them to the non-nested ones if ( mappingsKeyedByProperty.isEmpty() && !nonNested.isEmpty() ) { @@ -625,15 +612,15 @@ else if ( mappingsKeyedByProperty.isEmpty() && nonNested.isEmpty() ) { * @param hasNoMappings parameter indicating whether there were any extracted mappings for this target property * @param sourceParameter the source parameter for which the grouping is being done * - * @return a list with valid single target references + * @return a set with valid single target references */ - private List extractSingleTargetReferencesToUseAndPopulateSourceParameterMappings( - List singleTargetReferences, List sourceParameterMappings, boolean hasNoMappings, - Parameter sourceParameter) { - List singleTargetReferencesToUse = null; + private Set extractSingleTargetReferencesToUseAndPopulateSourceParameterMappings( + Set singleTargetReferences, Set sourceParameterMappings, + boolean hasNoMappings, Parameter sourceParameter) { + Set singleTargetReferencesToUse = null; if ( singleTargetReferences != null ) { - singleTargetReferencesToUse = new ArrayList( singleTargetReferences.size() ); - for ( Mapping mapping : singleTargetReferences ) { + singleTargetReferencesToUse = new LinkedHashSet<>( singleTargetReferences.size() ); + for ( MappingReference mapping : singleTargetReferences ) { if ( mapping.getSourceReference() == null || !mapping.getSourceReference().isValid() || !sourceParameter.equals( mapping.getSourceReference().getParameter() ) ) { // If the mapping has no sourceReference, it is not valid or it does not have the same source @@ -655,32 +642,57 @@ private List extractSingleTargetReferencesToUseAndPopulateSourceParamet return singleTargetReferencesToUse; } - private Map> groupByTargetName(List mappingList) { - Map> result = new LinkedHashMap>(); - for ( Mapping mapping : mappingList ) { - if ( !result.containsKey( mapping.getTargetName() ) ) { - result.put( mapping.getTargetName(), new ArrayList() ); + private PropertyMapping createPropertyMappingForNestedTarget(MappingReferences mappingReferences, + String targetPropertyName, + SourceReference sourceReference, + boolean forceUpdateMethod) { + + Accessor targetWriteAccessor = targetPropertiesWriteAccessors.get( targetPropertyName ); + ReadAccessor targetReadAccessor = targetType.getReadAccessor( + targetPropertyName, + method.getSourceParameters().size() == 1 + ); + if ( targetWriteAccessor == null ) { + Set readAccessors = targetType.getPropertyReadAccessors().keySet(); + String mostSimilarProperty = Strings.getMostSimilarWord( targetPropertyName, readAccessors ); + + for ( MappingReference mappingReference : mappingReferences.getMappingReferences() ) { + MappingOptions mapping = mappingReference.getMapping(); + List pathProperties = new ArrayList<>( mappingReference.getTargetReference() + .getPathProperties() ); + if ( !pathProperties.isEmpty() ) { + pathProperties.set( pathProperties.size() - 1, mostSimilarProperty ); + } + + mappingContext.getMessager() + .printMessage( + mapping.getElement(), + mapping.getMirror(), + mapping.getTargetAnnotationValue(), + Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_TYPE, + targetPropertyName, + targetType.describe(), + mapping.getTargetName(), + Strings.join( pathProperties, "." ) + ); } - result.get( mapping.getTargetName() ).add( mapping ); + + errorOccurred = true; + return null; } - return result; - } - private PropertyMapping createPropertyMappingForNestedTarget(MappingOptions mappingOptions, - PropertyEntry targetProperty, SourceReference sourceReference, boolean forceUpdateMethod) { - PropertyMapping propertyMapping = new PropertyMapping.PropertyMappingBuilder() + return new PropertyMapping.PropertyMappingBuilder() .mappingContext( mappingContext ) .sourceMethod( method ) - .targetProperty( targetProperty ) - .targetPropertyName( targetProperty.getName() ) + .target( targetPropertyName, targetReadAccessor, targetWriteAccessor ) .sourceReference( sourceReference ) .existingVariableNames( existingVariableNames ) - .dependsOn( mappingOptions.collectNestedDependsOn() ) - .forgeMethodWithMappingOptions( mappingOptions ) + .dependsOn( mappingReferences.collectNestedDependsOn() ) + .forgeMethodWithMappingReferences( mappingReferences ) .forceUpdateMethod( forceUpdateMethod ) .forgedNamedBased( false ) + .options( method.getOptions().getBeanMapping() ) .build(); - return propertyMapping; } /** @@ -692,16 +704,16 @@ private PropertyMapping createPropertyMappingForNestedTarget(MappingOptions mapp * @param singleTargetReferences to use * @param keyExtractor to be used to extract a key */ - private void populateWithSingleTargetReferences(Map> map, - List singleTargetReferences, Extractor keyExtractor) { + private void populateWithSingleTargetReferences(Map> map, + Set singleTargetReferences, Function keyExtractor) { if ( singleTargetReferences != null ) { //This are non nested target references only their property needs to be added as they most probably // define it - for ( Mapping mapping : singleTargetReferences ) { + for ( MappingReference mapping : singleTargetReferences ) { if ( mapping.getSourceReference() != null && mapping.getSourceReference().isValid() ) { K key = keyExtractor.apply( mapping.getSourceReference() ); - if ( key != null && !map.containsKey( key ) ) { - map.put( key, new ArrayList() ); + if ( key != null ) { + map.computeIfAbsent( key, keyValue -> new LinkedHashSet<>() ); } } } @@ -710,11 +722,11 @@ private void populateWithSingleTargetReferences(Map> map, } private static class GroupedBySourceParameters { - private final Map> groupedBySourceParameter; - private final List notProcessedAppliesToAll; + private final Map> groupedBySourceParameter; + private final Set notProcessedAppliesToAll; - private GroupedBySourceParameters(Map> groupedBySourceParameter, - List notProcessedAppliesToAll) { + private GroupedBySourceParameters(Map> groupedBySourceParameter, + Set notProcessedAppliesToAll) { this.groupedBySourceParameter = groupedBySourceParameter; this.notProcessedAppliesToAll = notProcessedAppliesToAll; } @@ -725,20 +737,24 @@ private GroupedBySourceParameters(Map> groupedBySourceP * references (target references that were not nested). */ private static class GroupedTargetReferences { - private final Map> poppedTargetReferences; - private final Map> singleTargetReferences; - private final boolean errorOccurred; + private final Map> poppedTargetReferences; + private final Map> singleTargetReferences; - private GroupedTargetReferences(Map> poppedTargetReferences, - Map> singleTargetReferences, boolean errorOccurred) { + private GroupedTargetReferences(Map> poppedTargetReferences, + Map> singleTargetReferences) { this.poppedTargetReferences = poppedTargetReferences; this.singleTargetReferences = singleTargetReferences; - this.errorOccurred = errorOccurred; + } + + @Override + public String toString() { + return "GroupedTargetReferences{" + "poppedTargetReferences=" + poppedTargetReferences + + ", singleTargetReferences=" + singleTargetReferences + "}"; } } /** - * This class is used to group Source references in respected to the nestings that they have. + * This class is used to group Source references in respected to the nesting that they have. * * This class contains all groupings by Property Entries if they are nested, or a list of all the other options * that could not have been popped. @@ -772,19 +788,26 @@ private GroupedTargetReferences(Map> poppedTargetRe */ private static class GroupedSourceReferences { - private final Map> groupedBySourceReferences; - private final List nonNested; - private final List notProcessedAppliesToAll; - private final List sourceParameterMappings; + private final Map> groupedBySourceReferences; + private final Set nonNested; + private final Set notProcessedAppliesToAll; + private final Set sourceParameterMappings; - private GroupedSourceReferences(Map> groupedBySourceReferences, - List nonNested, List notProcessedAppliesToAll, - List sourceParameterMappings) { + private GroupedSourceReferences(Map> groupedBySourceReferences, + Set nonNested, Set notProcessedAppliesToAll, + Set sourceParameterMappings) { this.groupedBySourceReferences = groupedBySourceReferences; this.nonNested = nonNested; this.notProcessedAppliesToAll = notProcessedAppliesToAll; this.sourceParameterMappings = sourceParameterMappings; } + + @Override + public String toString() { + return "GroupedSourceReferences{" + "groupedBySourceReferences=" + groupedBySourceReferences + + ", nonNested=" + nonNested + ", notProcessedAppliesToAll=" + notProcessedAppliesToAll + + ", sourceParameterMappings=" + sourceParameterMappings + '}'; + } } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/NoArgumentConstructor.java b/processor/src/main/java/org/mapstruct/ap/internal/model/NoArgumentConstructor.java new file mode 100644 index 0000000000..1101c15891 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/NoArgumentConstructor.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Collections; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * Represents a constructor that is used for constructor injection. + * + * @author Sjaak Derksen + */ +public class NoArgumentConstructor extends ModelElement implements Constructor { + + private final String name; + private final Set fragments; + + public NoArgumentConstructor(String name, Set fragments) { + this.name = name; + this.fragments = fragments; + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + @Override + public String getName() { + return name; + } + + public Set getFragments() { + return fragments; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java index 0743987b40..89ee1baab2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/NormalTypeMappingMethod.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -34,17 +21,19 @@ */ public abstract class NormalTypeMappingMethod extends MappingMethod { private final MethodReference factoryMethod; - private final boolean overridden; private final boolean mapNullToDefault; - NormalTypeMappingMethod(Method method, Collection existingVariableNames, MethodReference factoryMethod, + private final List annotations; + + NormalTypeMappingMethod(Method method, List annotations, + Collection existingVariableNames, MethodReference factoryMethod, boolean mapNullToDefault, List beforeMappingReferences, List afterMappingReferences) { super( method, existingVariableNames, beforeMappingReferences, afterMappingReferences ); this.factoryMethod = factoryMethod; - this.overridden = method.overridesMethod(); this.mapNullToDefault = mapNullToDefault; + this.annotations = annotations; } @Override @@ -55,6 +44,12 @@ public Set getImportTypes() { types.addAll( getReturnType().getImplementationType().getImportTypes() ); } } + else if ( factoryMethod != null ) { + types.addAll( factoryMethod.getImportTypes() ); + } + for ( Annotation annotation : annotations ) { + types.addAll( annotation.getImportTypes() ); + } return types; } @@ -62,14 +57,14 @@ public boolean isMapNullToDefault() { return mapNullToDefault; } - public boolean isOverridden() { - return overridden; - } - public MethodReference getFactoryMethod() { return this.factoryMethod; } + public List getAnnotations() { + return annotations; + } + @Override public int hashCode() { final int prime = 31; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ObjectFactoryMethodResolver.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ObjectFactoryMethodResolver.java index 8f779aed23..2d7da03abb 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ObjectFactoryMethodResolver.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ObjectFactoryMethodResolver.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; import java.util.List; - +import java.util.stream.Collectors; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; @@ -35,11 +20,13 @@ import org.mapstruct.ap.internal.model.source.SourceMethod; import org.mapstruct.ap.internal.model.source.selector.MethodSelectors; import org.mapstruct.ap.internal.model.source.selector.SelectedMethod; -import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; +import org.mapstruct.ap.internal.model.source.selector.SelectionContext; import org.mapstruct.ap.internal.util.Message; -import org.mapstruct.ap.internal.util.Strings; + +import static org.mapstruct.ap.internal.util.Collections.first; /** + * Factory for creating the appropriate object factory method. * * @author Sjaak Derksen */ @@ -52,45 +39,66 @@ private ObjectFactoryMethodResolver() { * returns a no arg factory method * * @param method target mapping method - * @param targetType return type to match * @param selectionParameters parameters used in the selection process - * @param ctx + * @param ctx the mapping builder context + * + * @return a method reference to the factory method, or null if no suitable, or ambiguous method found + */ + public static MethodReference getFactoryMethod( Method method, + SelectionParameters selectionParameters, + MappingBuilderContext ctx) { + return getFactoryMethod( method, method.getResultType(), selectionParameters, ctx ); + } + + /** + * returns a no arg factory method + * + * @param method target mapping method + * @param alternativeTarget alternative to {@link Method#getResultType()} e.g. when target is abstract + * @param selectionParameters parameters used in the selection process + * @param ctx the mapping builder context * * @return a method reference to the factory method, or null if no suitable, or ambiguous method found * */ public static MethodReference getFactoryMethod( Method method, - Type targetType, + Type alternativeTarget, SelectionParameters selectionParameters, MappingBuilderContext ctx) { - MethodSelectors selectors = - new MethodSelectors( ctx.getTypeUtils(), ctx.getElementUtils(), ctx.getTypeFactory() ); - - List> matchingFactoryMethods = - selectors.getMatchingMethods( - method, - getAllAvailableMethods( method, ctx.getSourceModel() ), - java.util.Collections. emptyList(), - targetType.getEffectiveType(), - SelectionCriteria.forFactoryMethods( selectionParameters ) ); - - if (matchingFactoryMethods.isEmpty()) { - return findBuilderFactoryMethod( targetType ); + + List> matchingFactoryMethods = getMatchingFactoryMethods( + method, + alternativeTarget, + selectionParameters, + ctx + ); + + if ( matchingFactoryMethods.isEmpty() ) { + return null; } if ( matchingFactoryMethods.size() > 1 ) { ctx.getMessager().printMessage( method.getExecutable(), - Message.GENERAL_AMBIGIOUS_FACTORY_METHOD, - targetType.getEffectiveType(), - Strings.join( matchingFactoryMethods, ", " ) ); + Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, + alternativeTarget.describe(), + matchingFactoryMethods.stream() + .map( SelectedMethod::getMethod ) + .map( Method::describe ) + .collect( Collectors.joining( ", " ) ) + ); return null; } SelectedMethod matchingFactoryMethod = first( matchingFactoryMethods ); + return getFactoryMethodReference( method, matchingFactoryMethod, ctx ); + } + + public static MethodReference getFactoryMethodReference(Method method, + SelectedMethod matchingFactoryMethod, MappingBuilderContext ctx) { Parameter providingParameter = method.getContextProvidedMethods().getParameterForProvidedMethod( matchingFactoryMethod.getMethod() ); @@ -112,8 +120,29 @@ java.util.Collections. emptyList(), } } - private static MethodReference findBuilderFactoryMethod(Type targetType) { - BuilderType builder = targetType.getBuilderType(); + public static List> getMatchingFactoryMethods( Method method, + Type alternativeTarget, + SelectionParameters selectionParameters, + MappingBuilderContext ctx) { + + MethodSelectors selectors = + new MethodSelectors( ctx.getTypeUtils(), ctx.getElementUtils(), ctx.getMessager(), null ); + + return selectors.getMatchingMethods( + getAllAvailableMethods( method, ctx.getSourceModel() ), + SelectionContext.forFactoryMethods( method, alternativeTarget, selectionParameters, ctx.getTypeFactory() ) + ); + } + + public static MethodReference getBuilderFactoryMethod(Method method, BuilderType builder ) { + Type returnType = method.getReturnType(); + if ( returnType.isOptionalType() ) { + returnType = returnType.getOptionalBaseType(); + } + return getBuilderFactoryMethod( returnType, builder ); + } + + public static MethodReference getBuilderFactoryMethod(Type typeToBuild, BuilderType builder ) { if ( builder == null ) { return null; } @@ -124,7 +153,7 @@ private static MethodReference findBuilderFactoryMethod(Type targetType) { return null; } - if ( !builder.getBuildingType().isAssignableTo( targetType ) ) { + if ( !builder.getBuildingType().isAssignableTo( typeToBuild ) ) { //TODO print error message return null; } @@ -145,7 +174,7 @@ private static List getAllAvailableMethods(Method method, List availableMethods = - new ArrayList( methodsProvidedByParams.size() + sourceModelMethods.size() ); + new ArrayList<>( methodsProvidedByParams.size() + sourceModelMethods.size() ); for ( SourceMethod methodProvidedByParams : methodsProvidedByParams ) { // add only methods from context that do have the @ObjectFactory annotation diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PresenceCheckMethodResolver.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PresenceCheckMethodResolver.java new file mode 100644 index 0000000000..3163614871 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PresenceCheckMethodResolver.java @@ -0,0 +1,215 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.mapstruct.ap.internal.gem.ConditionStrategyGem; +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.presence.NullPresenceCheck; +import org.mapstruct.ap.internal.model.presence.OptionalPresenceCheck; +import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; +import org.mapstruct.ap.internal.model.source.SelectionParameters; +import org.mapstruct.ap.internal.model.source.SourceMethod; +import org.mapstruct.ap.internal.model.source.selector.MethodSelectors; +import org.mapstruct.ap.internal.model.source.selector.SelectedMethod; +import org.mapstruct.ap.internal.model.source.selector.SelectionContext; +import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.NullabilityResolver; + +/** + * Factory for creating {@link PresenceCheck}s. + * + * @author Filip Hrisafov + */ +public final class PresenceCheckMethodResolver { + + private PresenceCheckMethodResolver() { + + } + + public static PresenceCheck getPresenceCheck( + Method method, + SelectionParameters selectionParameters, + MappingBuilderContext ctx + ) { + List> matchingMethods = findMatchingMethods( + method, + SelectionContext.forPresenceCheckMethods( method, selectionParameters, ctx.getTypeFactory() ), + ctx + ); + + if ( matchingMethods.isEmpty() ) { + return null; + } + + if ( matchingMethods.size() > 1 ) { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.GENERAL_AMBIGUOUS_PRESENCE_CHECK_METHOD, + selectionParameters.getSourceRHS().getSourceType().describe(), + matchingMethods.stream() + .map( SelectedMethod::getMethod ) + .map( Method::describe ) + .collect( Collectors.joining( ", " ) ) + ); + + return null; + } + + SelectedMethod matchingMethod = matchingMethods.get( 0 ); + + MethodReference methodReference = getPresenceCheckMethodReference( method, matchingMethod, ctx ); + + return new MethodReferencePresenceCheck( methodReference ); + + } + + public static PresenceCheck getPresenceCheckForSourceParameter( + Method method, + SelectionParameters selectionParameters, + Parameter sourceParameter, + MappingBuilderContext ctx + ) { + List> matchingMethods = findMatchingMethods( + method, + SelectionContext.forSourceParameterPresenceCheckMethods( + method, + selectionParameters, + sourceParameter, + ctx.getTypeFactory() + ), + ctx + ); + + if ( matchingMethods.isEmpty() ) { + if ( sourceParameter.getType().isOptionalType() ) { + return new OptionalPresenceCheck( sourceParameter.getName(), ctx.getVersionInformation() ); + } + else if ( !sourceParameter.getType().isPrimitive() ) { + // If the source parameter is @NonNull (JSpecify), skip the null guard entirely. + // Resolved in the mapper's @NullMarked scope since the parameter is declared in the mapper interface. + if ( ctx.getNullabilityInMapperScope( sourceParameter.getElement() ) + == NullabilityResolver.Nullability.NON_NULL ) { + ctx.getMessager().note( 2, + Message.PROPERTYMAPPING_JSPECIFY_SKIP_METHOD_GUARD_NON_NULL_PARAM, + sourceParameter.getName() + ); + return null; + } + return new NullPresenceCheck( sourceParameter.getName() ); + } + return null; + } + + if ( matchingMethods.size() > 1 ) { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.GENERAL_AMBIGUOUS_SOURCE_PARAMETER_CHECK_METHOD, + sourceParameter.getType().describe(), + matchingMethods.stream() + .map( SelectedMethod::getMethod ) + .map( Method::describe ) + .collect( Collectors.joining( ", " ) ) + ); + + return null; + } + + SelectedMethod matchingMethod = matchingMethods.get( 0 ); + + MethodReference methodReference = getPresenceCheckMethodReference( method, matchingMethod, ctx ); + + return new MethodReferencePresenceCheck( methodReference ); + + } + + private static List> findMatchingMethods( + Method method, + SelectionContext selectionContext, + MappingBuilderContext ctx + ) { + MethodSelectors selectors = new MethodSelectors( + ctx.getTypeUtils(), + ctx.getElementUtils(), + ctx.getMessager(), + null + ); + + return selectors.getMatchingMethods( + getAllAvailableMethods( method, ctx.getSourceModel(), selectionContext.getSelectionCriteria() ), + selectionContext + ); + } + + private static MethodReference getPresenceCheckMethodReference( + Method method, + SelectedMethod matchingMethod, + MappingBuilderContext ctx + ) { + + Parameter providingParameter = + method.getContextProvidedMethods().getParameterForProvidedMethod( matchingMethod.getMethod() ); + if ( providingParameter != null ) { + return MethodReference.forParameterProvidedMethod( + matchingMethod.getMethod(), + providingParameter, + matchingMethod.getParameterBindings() + ); + } + else { + MapperReference ref = MapperReference.findMapperReference( + ctx.getMapperReferences(), + matchingMethod.getMethod() + ); + + return MethodReference.forMapperReference( + matchingMethod.getMethod(), + ref, + matchingMethod.getParameterBindings() + ); + } + } + + private static List getAllAvailableMethods(Method method, List sourceModelMethods, + SelectionCriteria selectionCriteria) { + ParameterProvidedMethods contextProvidedMethods = method.getContextProvidedMethods(); + if ( contextProvidedMethods.isEmpty() ) { + return sourceModelMethods; + } + + List methodsProvidedByParams = contextProvidedMethods + .getAllProvidedMethodsInParameterOrder( method.getContextParameters() ); + + List availableMethods = + new ArrayList<>( methodsProvidedByParams.size() + sourceModelMethods.size() ); + + for ( SourceMethod methodProvidedByParams : methodsProvidedByParams ) { + if ( selectionCriteria.isPresenceCheckRequired() ) { + // add only methods from context that do have the @Condition for properties annotation + if ( methodProvidedByParams.getConditionOptions() + .isStrategyApplicable( ConditionStrategyGem.PROPERTIES ) ) { + availableMethods.add( methodProvidedByParams ); + } + } + else if ( selectionCriteria.isSourceParameterCheckRequired() ) { + // add only methods from context that do have the @Condition for source parameters annotation + if ( methodProvidedByParams.getConditionOptions() + .isStrategyApplicable( ConditionStrategyGem.SOURCE_PARAMETERS ) ) { + availableMethods.add( methodProvidedByParams ); + } + } + } + availableMethods.addAll( sourceModelMethods ); + + return availableMethods; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java index 8440cb72d0..163c390b66 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/PropertyMapping.java @@ -1,68 +1,70 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.model.common.Assignment.AssignmentType.DIRECT; -import static org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism.ALWAYS; -import static org.mapstruct.ap.internal.util.Collections.first; -import static org.mapstruct.ap.internal.util.Collections.last; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Objects; import java.util.Set; - +import java.util.function.Supplier; import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.type.DeclaredType; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; import org.mapstruct.ap.internal.model.assignment.AdderWrapper; import org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper; import org.mapstruct.ap.internal.model.assignment.EnumConstantWrapper; import org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps; import org.mapstruct.ap.internal.model.assignment.SetterWrapper; +import org.mapstruct.ap.internal.model.assignment.StreamAdderWrapper; import org.mapstruct.ap.internal.model.assignment.UpdateWrapper; +import org.mapstruct.ap.internal.model.beanmapping.MappingReferences; +import org.mapstruct.ap.internal.model.beanmapping.PropertyEntry; +import org.mapstruct.ap.internal.model.beanmapping.SourceReference; import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.BuilderType; import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.ModelElement; import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; +import org.mapstruct.ap.internal.model.presence.AllPresenceChecksPresenceCheck; +import org.mapstruct.ap.internal.model.presence.JavaExpressionPresenceCheck; +import org.mapstruct.ap.internal.model.presence.NullPresenceCheck; +import org.mapstruct.ap.internal.model.presence.OptionalPresenceCheck; +import org.mapstruct.ap.internal.model.presence.SuffixPresenceCheck; +import org.mapstruct.ap.internal.model.source.DelegatingOptions; +import org.mapstruct.ap.internal.model.source.MappingControl; import org.mapstruct.ap.internal.model.source.MappingOptions; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; -import org.mapstruct.ap.internal.model.source.PropertyEntry; import org.mapstruct.ap.internal.model.source.SelectionParameters; -import org.mapstruct.ap.internal.model.source.SourceReference; -import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; -import org.mapstruct.ap.internal.util.AccessorNamingUtils; -import org.mapstruct.ap.internal.util.Executables; -import org.mapstruct.ap.internal.util.MapperConfiguration; +import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.NativeTypes; +import org.mapstruct.ap.internal.util.NullabilityResolver; import org.mapstruct.ap.internal.util.Strings; -import org.mapstruct.ap.internal.util.ValueProvider; import org.mapstruct.ap.internal.util.accessor.Accessor; +import org.mapstruct.ap.internal.util.accessor.AccessorType; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; + +import static org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem.ALWAYS; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.IGNORE; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_DEFAULT; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.SET_TO_NULL; +import static org.mapstruct.ap.internal.model.ForgedMethod.forElementMapping; +import static org.mapstruct.ap.internal.model.ForgedMethod.forParameterMapping; +import static org.mapstruct.ap.internal.model.ForgedMethod.forPropertyMapping; +import static org.mapstruct.ap.internal.model.common.Assignment.AssignmentType.DIRECT; /** * Represents the mapping between a source and target property, e.g. from {@code String Source#foo} to @@ -74,52 +76,30 @@ public class PropertyMapping extends ModelElement { private final String name; + private final String sourcePropertyName; private final String sourceBeanName; private final String targetWriteAccessorName; - private final ValueProvider targetReadAccessorProvider; + private final ReadAccessor targetReadAccessorProvider; private final Type targetType; private final Assignment assignment; - private final List dependsOn; + private final Set dependsOn; private final Assignment defaultValueAssignment; - - public enum TargetWriteAccessorType { - FIELD, - GETTER, - SETTER, - ADDER; - - public static TargetWriteAccessorType of(AccessorNamingUtils accessorNaming, Accessor accessor) { - if ( accessorNaming.isSetterMethod( accessor ) ) { - return TargetWriteAccessorType.SETTER; - } - else if ( accessorNaming.isAdderMethod( accessor ) ) { - return TargetWriteAccessorType.ADDER; - } - else if ( accessorNaming.isGetterMethod( accessor ) ) { - return TargetWriteAccessorType.GETTER; - } - else { - return TargetWriteAccessorType.FIELD; - } - } - - public static boolean isFieldAssignment(TargetWriteAccessorType accessorType) { - return accessorType == FIELD; - } - } + private final boolean constructorMapping; @SuppressWarnings("unchecked") private static class MappingBuilderBase> extends AbstractBaseBuilder { protected Accessor targetWriteAccessor; - protected TargetWriteAccessorType targetWriteAccessorType; + protected AccessorType targetWriteAccessorType; protected Type targetType; - protected Accessor targetReadAccessor; + protected BuilderType targetBuilderType; + protected ReadAccessor targetReadAccessor; protected String targetPropertyName; + protected String sourcePropertyName; - protected List dependsOn; + protected Set dependsOn; protected Set existingVariableNames; - protected AnnotationMirror mirror; + protected AnnotationMirror positionHint; MappingBuilderBase(Class selfType) { super( selfType ); @@ -129,60 +109,28 @@ public T sourceMethod(Method sourceMethod) { return super.method( sourceMethod ); } - public T targetProperty(PropertyEntry targetProp) { - this.targetReadAccessor = targetProp.getReadAccessor(); - this.targetWriteAccessor = targetProp.getWriteAccessor(); - this.targetType = targetProp.getType(); - this.targetWriteAccessorType = TargetWriteAccessorType.of( ctx.getAccessorNaming(), targetWriteAccessor ); - return (T) this; - } - - public T targetReadAccessor(Accessor targetReadAccessor) { + public T target(String targetPropertyName, ReadAccessor targetReadAccessor, Accessor targetWriteAccessor) { + this.targetPropertyName = targetPropertyName; this.targetReadAccessor = targetReadAccessor; - return (T) this; - } - - public T targetWriteAccessor(Accessor targetWriteAccessor) { this.targetWriteAccessor = targetWriteAccessor; - this.targetWriteAccessorType = TargetWriteAccessorType.of( ctx.getAccessorNaming(), targetWriteAccessor ); - this.targetType = determineTargetType(); - + this.targetType = ctx.getTypeFactory().getType( targetWriteAccessor.getAccessedType() ); + BuilderGem builder = method.getOptions().getBeanMapping().getBuilder(); + this.targetBuilderType = ctx.getTypeFactory().builderTypeFor( this.targetType, builder ); + this.targetWriteAccessorType = targetWriteAccessor.getAccessorType(); return (T) this; } T mirror(AnnotationMirror mirror) { - this.mirror = mirror; + this.positionHint = mirror; return (T) this; } - private Type determineTargetType() { - // This is a bean mapping method, so we know the result is a declared type - Type mappingType = method.getResultType(); - if ( !method.isUpdateMethod() ) { - mappingType = mappingType.getEffectiveType(); - } - DeclaredType resultType = (DeclaredType) mappingType.getTypeMirror(); - - switch ( targetWriteAccessorType ) { - case ADDER: - case SETTER: - return ctx.getTypeFactory() - .getSingleParameter( resultType, targetWriteAccessor ) - .getType(); - case GETTER: - case FIELD: - default: - return ctx.getTypeFactory() - .getReturnType( resultType, targetWriteAccessor ); - } - } - - public T targetPropertyName(String targetPropertyName) { - this.targetPropertyName = targetPropertyName; + public T sourcePropertyName(String sourcePropertyName) { + this.sourcePropertyName = sourcePropertyName; return (T) this; } - public T dependsOn(List dependsOn) { + public T dependsOn(Set dependsOn) { this.dependsOn = dependsOn; return (T) this; } @@ -193,7 +141,7 @@ public T existingVariableNames(Set existingVariableNames) { } protected boolean isFieldAssignment() { - return targetWriteAccessorType == TargetWriteAccessorType.FIELD; + return targetWriteAccessorType.isFieldAssignment(); } } @@ -202,13 +150,17 @@ public static class PropertyMappingBuilder extends MappingBuilderBase do a null / presence check + return true; + } + + if ( nvpms == SET_TO_DEFAULT || nvpms == IGNORE ) { + // NullValuePropertyMapping is SET_TO_DEFAULT or IGNORE -> do a null check + return true; + } + + if ( rhs.getType().isConverted() ) { + // A type conversion is applied, so a null check is required + return true; + } + + if ( rhs.getType().isDirect() && targetType.isPrimitive() ) { + // If the type is direct and the target type is primitive (i.e. we are unboxing) then check is needed + return true; + } + + if ( hasDefaultValueOrDefaultExpression() ) { + // If there is default value defined then a check is needed + return true; + } + + // JSpecify annotations take precedence over NullValueCheckStrategy + NullabilityResolver resolver = ctx.getNullabilityResolver(); + NullabilityResolver.Nullability targetNullability = resolver.getSetterNullability( + targetWriteAccessor.getElement(), this::targetDeclaringTypeIsNullMarked + ); + Boolean jspecifyDecision = resolver.requiresNullCheck( sourceNullability, targetNullability ); + if ( jspecifyDecision != null ) { + ctx.getMessager().note( 2, + jspecifyDecision + ? Message.PROPERTYMAPPING_JSPECIFY_ADD_NULL_CHECK + : Message.PROPERTYMAPPING_JSPECIFY_SKIP_NULL_CHECK, + targetPropertyName, + sourceNullability, + targetNullability + ); + return jspecifyDecision; + } + + if ( nvcs == ALWAYS ) { + // NullValueCheckStrategy is ALWAYS -> do a null check + return true; + } + + return false; + } + + private NullabilityResolver.Nullability getSourceJSpecifyNullability() { + if ( sourceReference == null ) { + return NullabilityResolver.Nullability.UNKNOWN; + } + List entries = sourceReference.getPropertyEntries(); + if ( !entries.isEmpty() ) { + // A source chain can only be treated as @NonNull when every accessor along the + // chain is @NonNull. If any intermediate accessor is @Nullable, the chain may + // yield null even when the deepest accessor is @NonNull. + Type enclosingType = sourceReference.getParameter().getType(); + NullabilityResolver.Nullability chain = NullabilityResolver.Nullability.NON_NULL; + for ( PropertyEntry entry : entries ) { + if ( entry.getReadAccessor() == null ) { + return NullabilityResolver.Nullability.UNKNOWN; + } + NullabilityResolver.Nullability current = ctx.getNullabilityResolver().getNullability( + entry.getReadAccessor().getElement(), enclosingType::isNullMarked + ); + if ( current == NullabilityResolver.Nullability.NULLABLE ) { + return NullabilityResolver.Nullability.NULLABLE; + } + if ( current == NullabilityResolver.Nullability.UNKNOWN ) { + chain = NullabilityResolver.Nullability.UNKNOWN; + } + enclosingType = entry.getType(); + } + return chain; + } + // Direct parameter mapping: no property entries, the source is the parameter itself. + // Use the mapper type for @NullMarked scope resolution since the parameter is declared there. + Parameter parameter = sourceReference.getParameter(); + if ( parameter != null && parameter.getElement() != null ) { + return ctx.getNullabilityInMapperScope( parameter.getElement() ); + } + return NullabilityResolver.Nullability.UNKNOWN; + } + + /** + * Resolves whether the type that declares the target write accessor (i.e. the bean that + * owns the setter or field) is in a JSpecify {@code @NullMarked} scope. This is the correct + * scope for deciding whether an unannotated setter parameter or field should be treated as + * {@code @NonNull} — walking from the property value type (e.g. {@code String}) does not + * reach the bean's declaration. + */ + private boolean targetDeclaringTypeIsNullMarked() { + Element targetElement = targetWriteAccessor.getElement(); + if ( targetElement == null ) { + return false; + } + Element declaring = targetElement.getEnclosingElement(); + if ( !( declaring instanceof TypeElement ) ) { + return false; + } + return ctx.getTypeFactory().getType( declaring.asType() ).isNullMarked(); + } + + private boolean hasDefaultValueOrDefaultExpression() { + return defaultValue != null || defaultJavaExpression != null; + } + private Assignment assignToPlainViaAdder( Assignment rightHandSide) { Assignment result = rightHandSide; - if ( result.getSourceType().isCollectionType() ) { - result = new AdderWrapper( result, method.getThrownTypes(), isFieldAssignment(), targetPropertyName ); + String adderIteratorName = sourcePropertyName == null ? targetPropertyName : sourcePropertyName; + if ( result.getSourceType().isIterableType() ) { + result = new AdderWrapper( result, method.getThrownTypes(), isFieldAssignment(), adderIteratorName ); + } + else if ( result.getSourceType().isStreamType() ) { + result = new StreamAdderWrapper( + result, method.getThrownTypes(), isFieldAssignment(), adderIteratorName ); } else { // Possibly adding null to a target collection. So should be surrounded by an null check. - result = new SetterWrapper( result, method.getThrownTypes(), ALWAYS, isFieldAssignment(), targetType ); + // TODO: what triggers this else branch? Should nvcs, nvpms be applied? + result = new SetterWrapper( result, + method.getThrownTypes(), + isFieldAssignment(), + true, + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT, + hasTwoOrMoreSettersWithName(), + targetType + ); } return result; } - private Assignment assignToCollection(Type targetType, TargetWriteAccessorType targetAccessorType, + private boolean hasTwoOrMoreSettersWithName() { + Element enclosingClass = this.targetWriteAccessor.getElement().getEnclosingElement(); + if ( enclosingClass == null || !( ElementKind.CLASS.equals( enclosingClass.getKind() ) + || ElementKind.INTERFACE.equals( enclosingClass.getKind() ) ) ) { + return false; + } + String simpleWriteAccessorName = this.targetWriteAccessor.getSimpleName(); + boolean firstMatchFound = false; + for ( Accessor setter : ctx.getTypeFactory().getType( enclosingClass.asType() ).getSetters() ) { + if ( setter.getSimpleName().equals( simpleWriteAccessorName ) ) { + if ( firstMatchFound ) { + return true; + } + firstMatchFound = true; + } + } + return false; + } + + private Assignment assignToCollection(Type targetType, AccessorType targetAccessorType, Assignment rhs) { return new CollectionAssignmentBuilder() .mappingBuilderContext( ctx ) @@ -469,49 +749,64 @@ private Assignment assignToCollection(Type targetType, TargetWriteAccessorType t .targetAccessorType( targetAccessorType ) .rightHandSide( rightHandSide ) .assignment( rhs ) + .nullValueCheckStrategy( hasDefaultValueOrDefaultExpression() ? ALWAYS : nvcs ) + .nullValuePropertyMappingStrategy( nvpms ) + .sourceJSpecifyNullability( getSourceJSpecifyNullability() ) .build(); } private Assignment assignToArray(Type targetType, Assignment rightHandSide) { Type arrayType = ctx.getTypeFactory().getType( Arrays.class ); - Assignment assignment = new ArrayCopyWrapper( + //TODO init default value + return new ArrayCopyWrapper( rightHandSide, targetPropertyName, arrayType, targetType, - isFieldAssignment() - ); - return assignment; + isFieldAssignment(), + nvpms == SET_TO_NULL && !targetType.isPrimitive(), + nvpms == SET_TO_DEFAULT ); } private SourceRHS getSourceRHS( SourceReference sourceReference ) { Parameter sourceParam = sourceReference.getParameter(); - List propertyEntries = sourceReference.getPropertyEntries(); + PropertyEntry propertyEntry = sourceReference.getDeepestProperty(); // parameter reference - if ( propertyEntries.isEmpty() ) { - return new SourceRHS( sourceParam.getName(), - sourceParam.getType(), - existingVariableNames, - sourceReference.toString() + if ( propertyEntry == null ) { + SourceRHS sourceRHS = new SourceRHS( + sourceParam.getName(), + sourceParam.getType(), + existingVariableNames, + sourceReference.toString() ); + sourceRHS.setSourcePresenceCheckerReference( getSourcePresenceCheckerRef( + sourceReference, + sourceRHS + ) ); + return sourceRHS; } // simple property - else if ( propertyEntries.size() == 1 ) { - PropertyEntry propertyEntry = propertyEntries.get( 0 ); - String sourceRef = sourceParam.getName() + "." + ValueProvider.of( propertyEntry.getReadAccessor() ); - return new SourceRHS( sourceParam.getName(), - sourceRef, - getSourcePresenceCheckerRef( sourceReference ), - propertyEntry.getType(), - existingVariableNames, - sourceReference.toString() + else if ( !sourceReference.isNested() ) { + String sourceRef = sourceParam.getName() + "." + propertyEntry.getReadAccessor().getReadValueSource(); + SourceRHS sourceRHS = new SourceRHS( + sourceParam.getName(), + sourceRef, + null, + propertyEntry.getType(), + existingVariableNames, + sourceReference.toString() ); + sourceRHS.setSourcePresenceCheckerReference( getSourcePresenceCheckerRef( + sourceReference, + sourceRHS + ) ); + return sourceRHS; } // nested property given as dot path else { - Type sourceType = last( propertyEntries ).getType(); + Type sourceType = propertyEntry.getType(); if ( sourceType.isPrimitive() && !targetType.isPrimitive() ) { // Handle null's. If the forged method needs to be mapped to an object, the forged method must be // able to return null. So in that case primitive types are mapped to their corresponding wrapped @@ -519,20 +814,11 @@ else if ( propertyEntries.size() == 1 ) { sourceType = ctx.getTypeFactory().getWrappedType( sourceType ); } - // copy mapper configuration from the source method, its the same mapper - MapperConfiguration config = method.getMapperConfiguration(); - // forge a method from the parameter type to the last entry type. String forgedName = Strings.joinAndCamelize( sourceReference.getElementNames() ); - forgedName = Strings.getSaveVariableName( forgedName, ctx.getNamesOfMappingsToGenerate() ); - ForgedMethod methodRef = new ForgedMethod( - forgedName, - sourceReference.getParameter().getType(), - sourceType, - config, - method.getExecutable(), - Collections. emptyList(), - ParameterProvidedMethods.empty() ); + forgedName = Strings.getSafeVariableName( forgedName, ctx.getReservedNames() ); + Type sourceParameterType = sourceReference.getParameter().getType(); + ForgedMethod methodRef = forParameterMapping( forgedName, sourceParameterType, sourceType, method ); NestedPropertyMappingMethod.Builder builder = new NestedPropertyMappingMethod.Builder(); NestedPropertyMappingMethod nestedPropertyMapping = builder @@ -551,108 +837,164 @@ Collections. emptyList(), String sourceRef = forgedName + "( " + sourceParam.getName() + " )"; SourceRHS sourceRhs = new SourceRHS( sourceParam.getName(), sourceRef, - getSourcePresenceCheckerRef( sourceReference ), + null, sourceType, existingVariableNames, sourceReference.toString() ); + sourceRhs.setSourcePresenceCheckerReference( getSourcePresenceCheckerRef( + sourceReference, + sourceRhs + ) ); // create a local variable to which forged method can be assigned. - String desiredName = last( sourceReference.getPropertyEntries() ).getName(); - sourceRhs.setSourceLocalVarName( sourceRhs.createLocalVarName( desiredName ) ); + String desiredName = propertyEntry.getName(); + sourceRhs.setSourceLocalVarName( sourceRhs.createUniqueVarName( desiredName ) ); return sourceRhs; } } - private String getSourcePresenceCheckerRef( SourceReference sourceReference ) { - String sourcePresenceChecker = null; + private PresenceCheck getSourcePresenceCheckerRef(SourceReference sourceReference, + SourceRHS sourceRHS) { + + if ( conditionJavaExpression != null ) { + return new JavaExpressionPresenceCheck( conditionJavaExpression ); + } + + SelectionParameters selectionParameters = this.selectionParameters != null ? + this.selectionParameters.withSourceRHS( sourceRHS ) : + SelectionParameters.forSourceRHS( sourceRHS ); + PresenceCheck presenceCheck = PresenceCheckMethodResolver.getPresenceCheck( + method, + selectionParameters, + ctx + ); + if ( presenceCheck != null ) { + return presenceCheck; + } + + PresenceCheck sourcePresenceChecker = null; if ( !sourceReference.getPropertyEntries().isEmpty() ) { Parameter sourceParam = sourceReference.getParameter(); // TODO is first correct here?? shouldn't it be last since the remainer is checked // in the forged method? - PropertyEntry propertyEntry = first( sourceReference.getPropertyEntries() ); + PropertyEntry propertyEntry = sourceReference.getShallowestProperty(); if ( propertyEntry.getPresenceChecker() != null ) { - sourcePresenceChecker = sourceParam.getName() - + "." + propertyEntry.getPresenceChecker().getSimpleName() + "()"; + List presenceChecks = new ArrayList<>(); + presenceChecks.add( new SuffixPresenceCheck( + sourceParam.getName(), + propertyEntry.getPresenceChecker().getPresenceCheckSuffix() + ) ); + + String variableName = sourceParam.getName() + "." + + propertyEntry.getReadAccessor().getReadValueSource(); + Type variableType = propertyEntry.getType(); + for ( int i = 1; i < sourceReference.getPropertyEntries().size(); i++ ) { + PropertyEntry entry = sourceReference.getPropertyEntries().get( i ); + if ( entry.getPresenceChecker() != null && entry.getReadAccessor() != null ) { + if ( variableType.isOptionalType() ) { + presenceChecks.add( new OptionalPresenceCheck( + variableName, + ctx.getVersionInformation() + ) ); + variableName = variableName + ".get()"; + } + else { + presenceChecks.add( new NullPresenceCheck( variableName ) ); + } + presenceChecks.add( new SuffixPresenceCheck( + variableName, + entry.getPresenceChecker().getPresenceCheckSuffix() + ) ); + variableName = variableName + "." + entry.getReadAccessor().getSimpleName() + "()"; + variableType = entry.getType(); + } + else { + break; + } + } + + if ( presenceChecks.size() == 1 ) { + sourcePresenceChecker = presenceChecks.get( 0 ); + } + else { + sourcePresenceChecker = new AllPresenceChecksPresenceCheck( presenceChecks ); + } } } return sourcePresenceChecker; } - private Assignment forgeStreamMapping(Type sourceType, Type targetType, SourceRHS source, - ExecutableElement element) { + private Assignment forgeStreamMapping(Type sourceType, Type targetType, SourceRHS source) { StreamMappingMethod.Builder builder = new StreamMappingMethod.Builder(); - return forgeWithElementMapping( sourceType, targetType, source, element, builder ); + return forgeWithElementMapping( sourceType, targetType, source, builder ); } - private Assignment forgeIterableMapping(Type sourceType, Type targetType, SourceRHS source, - ExecutableElement element) { + private Assignment forgeIterableMapping(Type sourceType, Type targetType, SourceRHS source) { IterableMappingMethod.Builder builder = new IterableMappingMethod.Builder(); - return forgeWithElementMapping( sourceType, targetType, source, element, builder ); + return forgeWithElementMapping( sourceType, targetType, source, builder ); } private Assignment forgeWithElementMapping(Type sourceType, Type targetType, SourceRHS source, - ExecutableElement element, ContainerMappingMethodBuilder builder) { - + ContainerMappingMethodBuilder builder) { + sourceType = sourceType.replaceSuperBoundWith( targetType, ctx.getTypeFactory().getType( Object.class ) ); targetType = targetType.withoutBounds(); - ForgedMethod methodRef = prepareForgedMethod( sourceType, targetType, source, element, "[]" ); + ForgedMethod methodRef = prepareForgedMethod( sourceType, targetType, source, "[]" ); - ContainerMappingMethod iterableMappingMethod = builder + Supplier mappingMethodCreator = () -> builder .mappingContext( ctx ) .method( methodRef ) .selectionParameters( selectionParameters ) .callingContextTargetPropertyName( targetPropertyName ) + .positionHint( positionHint ) .build(); - return createForgedAssignment( source, methodRef, iterableMappingMethod ); + return getOrCreateForgedAssignment( source, methodRef, mappingMethodCreator ); } - private ForgedMethod prepareForgedMethod(Type sourceType, Type targetType, SourceRHS source, - ExecutableElement element, String suffix) { + private ForgedMethod prepareForgedMethod(Type sourceType, Type targetType, SourceRHS source, String suffix) { String name = getName( sourceType, targetType ); - name = Strings.getSaveVariableName( name, ctx.getNamesOfMappingsToGenerate() ); + name = Strings.getSafeVariableName( name, ctx.getReservedNames() ); // copy mapper configuration from the source method, its the same mapper - MapperConfiguration config = method.getMapperConfiguration(); - return new ForgedMethod( - name, - sourceType, - targetType, - config, - element, - method.getContextParameters(), - method.getContextProvidedMethods(), - getForgedMethodHistory( source, suffix ), - null, - forgedNamedBased - ); + ForgedMethodHistory forgedMethodHistory = getForgedMethodHistory( source, suffix ); + return forElementMapping( name, sourceType, targetType, method, forgedMethodHistory, forgedNamedBased ); } - private Assignment forgeMapMapping(Type sourceType, Type targetType, SourceRHS source, - ExecutableElement element) { + private Assignment forgeMapMapping(Type sourceType, Type targetType, SourceRHS source) { targetType = targetType.withoutBounds(); - ForgedMethod methodRef = prepareForgedMethod( sourceType, targetType, source, element, "{}" ); + ForgedMethod methodRef = prepareForgedMethod( sourceType, targetType, source, "{}" ); MapMappingMethod.Builder builder = new MapMappingMethod.Builder(); - MapMappingMethod mapMappingMethod = builder + Supplier mapMappingMethodCreator = () -> builder .mappingContext( ctx ) .method( methodRef ) .build(); - return createForgedAssignment( source, methodRef, mapMappingMethod ); + return getOrCreateForgedAssignment( source, methodRef, mapMappingMethodCreator ); } private Assignment forgeMapping(SourceRHS sourceRHS) { - Type sourceType = sourceRHS.getSourceType(); + Type sourceType; + if ( targetWriteAccessorType == AccessorType.ADDER ) { + sourceType = sourceRHS.getSourceTypeForMatching(); + } + else { + sourceType = sourceRHS.getSourceType(); + } if ( forgedNamedBased && !canGenerateAutoSubMappingBetween( sourceType, targetType ) ) { return null; } + return forgeMapping( sourceType, targetType, sourceRHS ); + } + + private Assignment forgeMapping(Type sourceType, Type targetType, SourceRHS sourceRHS) { //Fail fast. If we could not find the method by now, no need to try if ( sourceType.isPrimitive() || targetType.isPrimitive() ) { @@ -660,31 +1002,29 @@ private Assignment forgeMapping(SourceRHS sourceRHS) { } String name = getName( sourceType, targetType ); - name = Strings.getSaveVariableName( name, ctx.getNamesOfMappingsToGenerate() ); + name = Strings.getSafeVariableName( name, ctx.getReservedNames() ); - List parameters = new ArrayList( method.getContextParameters() ); + List parameters = new ArrayList<>( method.getContextParameters() ); Type returnType; // there's only one case for forging a method with mapping options: nested target properties. // They should forge an update method only if we set the forceUpdateMethod. This is set to true, // because we are forging a Mapping for a method with multiple source parameters. // If the target type is enum, then we can't create an update method - if ( !targetType.isEnumType() && ( method.isUpdateMethod() || forceUpdateMethod ) ) { + if ( !targetType.isEnumType() && ( method.isUpdateMethod() || forceUpdateMethod ) + && targetWriteAccessorType != AccessorType.ADDER ) { parameters.add( Parameter.forForgedMappingTarget( targetType ) ); returnType = ctx.getTypeFactory().createVoidType(); } else { returnType = targetType; } - ForgedMethod forgedMethod = new ForgedMethod( - name, + ForgedMethod forgedMethod = forPropertyMapping( name, sourceType, returnType, - method.getMapperConfiguration(), - method.getExecutable(), parameters, - method.getContextProvidedMethods(), + method, getForgedMethodHistory( sourceRHS ), - forgeMethodWithMappingOptions, + forgeMethodWithMappingReferences, forgedNamedBased ); return createForgedAssignment( sourceRHS, forgedMethod ); @@ -740,6 +1080,7 @@ public static class ConstantMappingBuilder extends MappingBuilderBase null ); } else { @@ -799,27 +1152,33 @@ public PropertyMapping build() { if ( assignment != null ) { - if ( ctx.getAccessorNaming().isSetterMethod( targetWriteAccessor ) || - Executables.isFieldAccessor( targetWriteAccessor ) ) { + if ( targetWriteAccessor.getAccessorType() == AccessorType.SETTER || + targetWriteAccessor.getAccessorType().isFieldAssignment() ) { // target accessor is setter, so decorate assignment as setter if ( assignment.isCallingUpdateMethod() ) { if ( targetReadAccessor == null ) { ctx.getMessager().printMessage( method.getExecutable(), + positionHint, Message.CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE, targetPropertyName ); } - boolean mapNullToDefault = method.getMapperConfiguration(). - getNullValueMappingStrategy() == NullValueMappingStrategyPrism.RETURN_DEFAULT; - Assignment factoryMethod = ObjectFactoryMethodResolver.getFactoryMethod( method, targetType, null, ctx ); - assignment = new UpdateWrapper( assignment, method.getThrownTypes(), factoryMethod, - isFieldAssignment(), targetType, false, mapNullToDefault ); + assignment = new UpdateWrapper( + assignment, + method.getThrownTypes(), + factoryMethod, + isFieldAssignment(), + targetType, + false, + false, + false, + false ); } else { assignment = new SetterWrapper( assignment, method.getThrownTypes(), isFieldAssignment() ); @@ -838,22 +1197,20 @@ public PropertyMapping build() { else if ( errorMessageDetails == null ) { ctx.getMessager().printMessage( method.getExecutable(), - mirror, + positionHint, Message.CONSTANTMAPPING_MAPPING_NOT_FOUND, - sourceType, constantExpression, - targetType, + targetType.describe(), targetPropertyName ); } else { ctx.getMessager().printMessage( method.getExecutable(), - mirror, + positionHint, Message.CONSTANTMAPPING_MAPPING_NOT_FOUND_WITH_DETAILS, - sourceType, constantExpression, - targetType, + targetType.describe(), targetPropertyName, errorMessageDetails ); @@ -861,12 +1218,13 @@ else if ( errorMessageDetails == null ) { return new PropertyMapping( targetPropertyName, - targetWriteAccessor.getSimpleName().toString(), - ValueProvider.of( targetReadAccessor ), + targetWriteAccessor.getSimpleName(), + targetReadAccessor, targetType, assignment, dependsOn, - null + null, + targetWriteAccessorType == AccessorType.PARAMETER ); } @@ -882,9 +1240,10 @@ private Assignment getEnumAssignment() { else { ctx.getMessager().printMessage( method.getExecutable(), + positionHint, Message.CONSTANTMAPPING_NON_EXISTING_CONSTANT, constantExpression, - targetType, + targetType.describe(), targetPropertyName ); } @@ -909,8 +1268,8 @@ public JavaExpressionMappingBuilder javaExpression(String javaExpression) { public PropertyMapping build() { Assignment assignment = new SourceRHS( javaExpression, null, existingVariableNames, "" ); - if ( ctx.getAccessorNaming().isSetterMethod( targetWriteAccessor ) || - Executables.isFieldAccessor( targetWriteAccessor ) ) { + if ( targetWriteAccessor.getAccessorType() == AccessorType.SETTER || + targetWriteAccessor.getAccessorType().isFieldAssignment() ) { // setter, so wrap in setter assignment = new SetterWrapper( assignment, method.getThrownTypes(), isFieldAssignment() ); } @@ -925,12 +1284,13 @@ public PropertyMapping build() { return new PropertyMapping( targetPropertyName, - targetWriteAccessor.getSimpleName().toString(), - ValueProvider.of( targetReadAccessor ), + targetWriteAccessor.getSimpleName(), + targetReadAccessor, targetType, assignment, dependsOn, - null + null, + targetWriteAccessorType == AccessorType.PARAMETER ); } @@ -938,18 +1298,20 @@ public PropertyMapping build() { // Constructor for creating mappings of constant expressions. private PropertyMapping(String name, String targetWriteAccessorName, - ValueProvider targetReadAccessorProvider, - Type targetType, Assignment propertyAssignment, - List dependsOn, Assignment defaultValueAssignment ) { - this( name, null, targetWriteAccessorName, targetReadAccessorProvider, - targetType, propertyAssignment, dependsOn, defaultValueAssignment + ReadAccessor targetReadAccessorProvider, + Type targetType, Assignment propertyAssignment, + Set dependsOn, Assignment defaultValueAssignment, boolean constructorMapping) { + this( name, null, null, targetWriteAccessorName, targetReadAccessorProvider, + targetType, propertyAssignment, dependsOn, defaultValueAssignment, + constructorMapping ); } - private PropertyMapping(String name, String sourceBeanName, String targetWriteAccessorName, - ValueProvider targetReadAccessorProvider, Type targetType, + private PropertyMapping(String sourcePropertyName, String name, String sourceBeanName, + String targetWriteAccessorName, ReadAccessor targetReadAccessorProvider, Type targetType, Assignment assignment, - List dependsOn, Assignment defaultValueAssignment) { + Set dependsOn, Assignment defaultValueAssignment, boolean constructorMapping) { + this.sourcePropertyName = sourcePropertyName; this.name = name; this.sourceBeanName = sourceBeanName; this.targetWriteAccessorName = targetWriteAccessorName; @@ -957,8 +1319,9 @@ private PropertyMapping(String name, String sourceBeanName, String targetWriteAc this.targetType = targetType; this.assignment = assignment; - this.dependsOn = dependsOn != null ? dependsOn : Collections.emptyList(); + this.dependsOn = dependsOn != null ? dependsOn : Collections.emptySet(); this.defaultValueAssignment = defaultValueAssignment; + this.constructorMapping = constructorMapping; } /** @@ -968,6 +1331,10 @@ public String getName() { return name; } + public String getSourcePropertyName() { + return sourcePropertyName; + } + public String getSourceBeanName() { return sourceBeanName; } @@ -977,7 +1344,7 @@ public String getTargetWriteAccessorName() { } public String getTargetReadAccessorName() { - return targetReadAccessorProvider == null ? null : targetReadAccessorProvider.getValue(); + return targetReadAccessorProvider == null ? null : targetReadAccessorProvider.getReadValueSource(); } public Type getTargetType() { @@ -992,8 +1359,11 @@ public Assignment getDefaultValueAssignment() { return defaultValueAssignment; } + public boolean isConstructorMapping() { + return constructorMapping; + } + @Override - @SuppressWarnings("unchecked") public Set getImportTypes() { if ( defaultValueAssignment == null ) { return assignment.getImportTypes(); @@ -1005,7 +1375,7 @@ public Set getImportTypes() { ); } - public List getDependsOn() { + public Set getDependsOn() { return dependsOn; } @@ -1029,13 +1399,13 @@ public boolean equals(Object obj) { return false; } final PropertyMapping other = (PropertyMapping) obj; - if ( (this.name == null) ? (other.name != null) : !this.name.equals( other.name ) ) { + if ( !Objects.equals( name, other.name ) ) { return false; } - if ( this.targetType != other.targetType && (this.targetType == null || - !this.targetType.equals( other.targetType )) ) { + if ( !Objects.equals( targetType, other.targetType ) ) { return false; } + return true; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ServicesEntry.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ServicesEntry.java index d91ca0e5cf..0d97c1a523 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ServicesEntry.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ServicesEntry.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -25,6 +12,8 @@ import org.mapstruct.ap.internal.model.common.Type; /** + * Represents a service entry for the service loader file. + * * @author Christophe Labouisse on 14/07/2015. */ public class ServicesEntry extends ModelElement { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java index 6e2d067b86..3955bc47ce 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/StreamMappingMethod.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -28,6 +15,7 @@ import org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper; import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; @@ -64,9 +52,10 @@ protected Assignment getWrapper(Assignment assignment, Method method) { protected StreamMappingMethod instantiateMappingMethod(Method method, Collection existingVariables, Assignment assignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingMethods, - List afterMappingMethods, SelectionParameters selectionParameters) { + List afterMappingMethods, SelectionParameters selectionParameters, + PresenceCheck sourceParameterPresenceCheck) { - Set helperImports = new HashSet(); + Set helperImports = new HashSet<>(); if ( method.getResultType().isIterableType() ) { helperImports.add( ctx.getTypeFactory().getType( Collectors.class ) ); } @@ -76,9 +65,9 @@ protected StreamMappingMethod instantiateMappingMethod(Method method, Collection sourceParameterType.isIterableType() ) { helperImports.add( ctx.getTypeFactory().getType( StreamSupport.class ) ); } - return new StreamMappingMethod( method, + getMethodAnnotations(), existingVariables, assignment, factoryMethod, @@ -87,18 +76,21 @@ protected StreamMappingMethod instantiateMappingMethod(Method method, Collection beforeMappingMethods, afterMappingMethods, selectionParameters, - helperImports + helperImports, + sourceParameterPresenceCheck ); } } - - private StreamMappingMethod(Method method, Collection existingVariables, Assignment parameterAssignment, + //CHECKSTYLE:OFF + private StreamMappingMethod(Method method, List annotations, + Collection existingVariables, Assignment parameterAssignment, MethodReference factoryMethod, boolean mapNullToDefault, String loopVariableName, List beforeMappingReferences, List afterMappingReferences, - SelectionParameters selectionParameters, Set helperImports) { + SelectionParameters selectionParameters, Set helperImports, PresenceCheck sourceParameterPresenceCheck) { super( method, + annotations, existingVariables, parameterAssignment, factoryMethod, @@ -106,8 +98,10 @@ private StreamMappingMethod(Method method, Collection existingVariables, loopVariableName, beforeMappingReferences, afterMappingReferences, - selectionParameters + selectionParameters, + sourceParameterPresenceCheck ); + //CHECKSTYLE:ON this.helperImports = helperImports; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/SubclassMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/SubclassMapping.java new file mode 100644 index 0000000000..3ce42f68e5 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SubclassMapping.java @@ -0,0 +1,69 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.assignment.AssignmentWrapper; +import org.mapstruct.ap.internal.model.assignment.ReturnWrapper; +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * Represents the mapping between a Subclass and its mapping target. This will be used by a {@link BeanMappingMethod} + * that has {@link org.mapstruct.SubclassMapping} annotations applied to it. Before doing the normal mapping for that + * method it will first check if the source object is of the sourceType if so it will use the assignment instead. + * + * @author Ben Zegveld + */ +public class SubclassMapping extends ModelElement { + + private final Type sourceType; + private final Type targetType; + private final Assignment assignment; + private final String sourceArgument; + + public SubclassMapping(Type sourceType, String sourceArgument, Type targetType, Assignment assignment) { + this.sourceType = sourceType; + this.sourceArgument = sourceArgument; + this.targetType = targetType; + this.assignment = assignment; + } + + public Type getSourceType() { + return sourceType; + } + + @Override + public Set getImportTypes() { + return Collections.singleton( sourceType ); + } + + public AssignmentWrapper getAssignment() { + return new ReturnWrapper( assignment ); + } + + public String getSourceArgument() { + return sourceArgument; + } + + @Override + public boolean equals(final Object other) { + if ( !( other instanceof SubclassMapping ) ) { + return false; + } + SubclassMapping castOther = (SubclassMapping) other; + return Objects.equals( sourceType, castOther.sourceType ) && Objects.equals( targetType, castOther.targetType ); + } + + @Override + public int hashCode() { + return Objects.hash( sourceType, targetType ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingConstructorFragment.java b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingConstructorFragment.java new file mode 100644 index 0000000000..936a9a51ba --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingConstructorFragment.java @@ -0,0 +1,105 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConstructorFragment; +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A mapper instance field, initialized as null + * + * @author Sjaak Derksen + */ +public class SupportingConstructorFragment extends ModelElement { + + private final String variableName; + private final String templateName; + private final SupportingMappingMethod definingMethod; + + public SupportingConstructorFragment(SupportingMappingMethod definingMethod, + ConstructorFragment constructorFragment, String variableName) { + this.templateName = getTemplateNameForClass( constructorFragment.getClass() ); + this.definingMethod = definingMethod; + this.variableName = variableName; + } + + @Override + public String getTemplateName() { + return templateName; + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + public SupportingMappingMethod getDefiningMethod() { + return definingMethod; + } + + public String getVariableName() { + return variableName; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( variableName == null ) ? 0 : variableName.hashCode() ); + result = prime * result + ( ( templateName == null ) ? 0 : templateName.hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + SupportingConstructorFragment other = (SupportingConstructorFragment) obj; + + if ( !Objects.equals( variableName, other.variableName ) ) { + return false; + } + if ( !Objects.equals( templateName, other.templateName ) ) { + return false; + } + return true; + } + + public static void addAllFragmentsIn(Set supportingMappingMethods, + Set targets) { + for ( SupportingMappingMethod supportingMappingMethod : supportingMappingMethods ) { + SupportingConstructorFragment fragment = supportingMappingMethod.getSupportingConstructorFragment(); + if ( fragment != null ) { + targets.add( supportingMappingMethod.getSupportingConstructorFragment() ); + } + } + } + + public static SupportingConstructorFragment getSafeConstructorFragment(SupportingMappingMethod method, + ConstructorFragment fragment, + Field supportingField) { + if ( fragment == null ) { + return null; + } + + return new SupportingConstructorFragment( + method, + fragment, + supportingField != null ? supportingField.getVariableName() : null ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingField.java b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingField.java new file mode 100644 index 0000000000..2cac1ef351 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingField.java @@ -0,0 +1,71 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Map; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.FieldReference; +import org.mapstruct.ap.internal.util.Strings; + +/** + * supports the + * + * @author Sjaak Derksen + */ +public class SupportingField extends Field { + + private final String templateName; + private final Map templateParameter; + + private final SupportingMappingMethod definingMethod; + + public SupportingField(SupportingMappingMethod definingMethod, FieldReference fieldReference, String name) { + super( fieldReference.getType(), name, true ); + this.templateName = getTemplateNameForClass( fieldReference.getClass() ); + this.templateParameter = fieldReference.getTemplateParameter(); + this.definingMethod = definingMethod; + } + + @Override + public String getTemplateName() { + return templateName; + } + + public Map getTemplateParameter() { + return templateParameter; + } + + public SupportingMappingMethod getDefiningMethod() { + return definingMethod; + } + + public static void addAllFieldsIn(Set supportingMappingMethods, Set targets) { + for ( SupportingMappingMethod supportingMappingMethod : supportingMappingMethods ) { + Field field = supportingMappingMethod.getSupportingField(); + if ( field != null ) { + targets.add( field ); + } + } + } + + public static Field getSafeField(SupportingMappingMethod method, FieldReference ref, Set existingFields) { + if ( ref == null ) { + return null; + } + + String name = ref.getVariableName(); + for ( Field existingField : existingFields ) { + if ( existingField.getVariableName().equals( ref.getVariableName() ) + && existingField.getType().equals( ref.getType() ) ) { + // field already exists, use that one + return existingField; + } + } + name = Strings.getSafeVariableName( name, Field.getFieldNames( existingFields ) ); + return new SupportingField( method, ref, name ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingMappingMethod.java new file mode 100644 index 0000000000..9428454c1f --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/SupportingMappingMethod.java @@ -0,0 +1,129 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod; +import org.mapstruct.ap.internal.model.source.builtin.NewDatatypeFactoryConstructorFragment; + +/** + * A mapping method which is not based on an actual method declared in the original mapper interface but is added as + * private method to map a certain source/target type combination. Based on a {@link BuiltInMethod}. + * + * Specific templates all point to this class, for instance: + * {@link org.mapstruct.ap.internal.model.source.builtin.XmlGregorianCalendarToCalendar}, + * but also used fields and constructor elements, e.g. + * {@link org.mapstruct.ap.internal.model.common.FinalField} and + * {@link NewDatatypeFactoryConstructorFragment} + * + * @author Gunnar Morling + */ +public class SupportingMappingMethod extends MappingMethod { + + private final String templateName; + private final Set importTypes; + private final Field supportingField; + private final SupportingConstructorFragment supportingConstructorFragment; + private final Map templateParameter; + + public SupportingMappingMethod(BuiltInMethod method, Set existingFields) { + super( method ); + this.importTypes = method.getImportTypes(); + this.templateName = getTemplateNameForClass( method.getClass() ); + this.templateParameter = null; + this.supportingField = SupportingField.getSafeField( this, method.getFieldReference(), existingFields ); + this.supportingConstructorFragment = SupportingConstructorFragment.getSafeConstructorFragment( + this, + method.getConstructorFragment(), + this.supportingField ); + } + + public SupportingMappingMethod(HelperMethod method) { + super( method ); + this.importTypes = method.getImportTypes(); + this.templateName = getTemplateNameForClass( method.getClass() ); + this.templateParameter = null; + this.supportingField = null; + this.supportingConstructorFragment = null; + } + + @Override + public String getTemplateName() { + return templateName; + } + + @Override + public Set getImportTypes() { + return importTypes; + } + + /** + * Finds a {@link Type} by a given name. The {@code name} will be compared to the fully-qualified and also simple + * names of the {@code importTypes}. + * + * @param name Fully-qualified or simple name of the type. + * + * @return Found type, never null. + * + * @throws IllegalArgumentException In case no {@link Type} was found for given name. + */ + public Type findType(String name) { + for ( Type type : importTypes ) { + if ( type.getFullyQualifiedName().contentEquals( name ) ) { + return type; + } + if ( type.getName().contentEquals( name ) ) { + return type; + } + } + + throw new IllegalArgumentException( "No type for given name '" + name + "' found in 'importTypes'." ); + } + + public Field getSupportingField() { + return supportingField; + } + + public SupportingConstructorFragment getSupportingConstructorFragment() { + return supportingConstructorFragment; + } + + public Map getTemplateParameter() { + return templateParameter; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ( ( getName() == null ) ? 0 : getName().hashCode() ); + return result; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + SupportingMappingMethod other = (SupportingMappingMethod) obj; + + if ( !Objects.equals( getName(), other.getName() ) ) { + return false; + } + + return true; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ToOptionalTypeConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ToOptionalTypeConversion.java new file mode 100644 index 0000000000..45bbc9d4b0 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ToOptionalTypeConversion.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * An inline conversion from a source to an optional of the source. + * + * @author Filip Hrisafov + */ +public class ToOptionalTypeConversion extends ModelElement implements Assignment { + + private final Assignment conversionAssignment; + private final Type targetType; + + public ToOptionalTypeConversion(Type targetType, Assignment conversionAssignment) { + this.conversionAssignment = conversionAssignment; + this.targetType = targetType; + } + + public Type getTargetType() { + return targetType; + } + + @Override + public Set getImportTypes() { + Set importTypes = new HashSet<>( conversionAssignment.getImportTypes() ); + importTypes.add( targetType ); + return importTypes; + } + + @Override + public List getThrownTypes() { + return conversionAssignment.getThrownTypes(); + } + + public Assignment getAssignment() { + return conversionAssignment; + } + + @Override + public String getSourceReference() { + return conversionAssignment.getSourceReference(); + } + + @Override + public boolean isSourceReferenceParameter() { + return conversionAssignment.isSourceReferenceParameter(); + } + + @Override + public PresenceCheck getSourcePresenceCheckerReference() { + return conversionAssignment.getSourcePresenceCheckerReference(); + } + + @Override + public Type getSourceType() { + return conversionAssignment.getSourceType(); + } + + @Override + public String createUniqueVarName(String desiredName) { + return conversionAssignment.createUniqueVarName( desiredName ); + } + + @Override + public String getSourceLocalVarName() { + return conversionAssignment.getSourceLocalVarName(); + } + + @Override + public void setSourceLocalVarName(String sourceLocalVarName) { + conversionAssignment.setSourceLocalVarName( sourceLocalVarName ); + } + + @Override + public String getSourceLoopVarName() { + return conversionAssignment.getSourceLoopVarName(); + } + + @Override + public void setSourceLoopVarName(String sourceLoopVarName) { + conversionAssignment.setSourceLoopVarName( sourceLoopVarName ); + } + + @Override + public String getSourceParameterName() { + return conversionAssignment.getSourceParameterName(); + } + + @Override + public void setAssignment(Assignment assignment) { + conversionAssignment.setAssignment( assignment ); + } + + @Override + public AssignmentType getType() { + return conversionAssignment.getType(); + } + + @Override + public boolean isCallingUpdateMethod() { + return false; + } + + @Override + public String toString() { + return targetType.getName() + ".of( " + conversionAssignment.toString() + " )"; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/TypeConversion.java b/processor/src/main/java/org/mapstruct/ap/internal/model/TypeConversion.java index 19c6a6f9eb..c5b4bc6915 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/TypeConversion.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/TypeConversion.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; @@ -24,6 +11,7 @@ import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; /** @@ -48,9 +36,9 @@ public class TypeConversion extends ModelElement implements Assignment { private Assignment assignment; public TypeConversion( Set importTypes, - List exceptionTypes, - String expression ) { - this.importTypes = new HashSet( importTypes ); + List exceptionTypes, + String expression ) { + this.importTypes = new HashSet<>( importTypes ); this.importTypes.addAll( exceptionTypes ); this.thrownTypes = exceptionTypes; @@ -92,7 +80,7 @@ public boolean isSourceReferenceParameter() { } @Override - public String getSourcePresenceCheckerReference() { + public PresenceCheck getSourcePresenceCheckerReference() { return assignment.getSourcePresenceCheckerReference(); } @@ -102,8 +90,8 @@ public Type getSourceType() { } @Override - public String createLocalVarName( String desiredName ) { - return assignment.createLocalVarName( desiredName ); + public String createUniqueVarName(String desiredName ) { + return assignment.createUniqueVarName( desiredName ); } @Override @@ -116,6 +104,16 @@ public void setSourceLocalVarName(String sourceLocalVarName) { assignment.setSourceLocalVarName( sourceLocalVarName ); } + @Override + public String getSourceLoopVarName() { + return assignment.getSourceLoopVarName(); + } + + @Override + public void setSourceLoopVarName(String sourceLoopVarName) { + assignment.setSourceLoopVarName( sourceLoopVarName ); + } + @Override public String getSourceParameterName() { return assignment.getSourceParameterName(); @@ -141,6 +139,12 @@ public Assignment.AssignmentType getType() { @Override public boolean isCallingUpdateMethod() { - return false; + return false; + } + + @Override + public String toString() { + String argument = getAssignment() != null ? getAssignment().toString() : getSourceReference(); + return openExpression + argument + closeExpression; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java index 6c9a057b31..82346fa8ac 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/ValueMappingMethod.java @@ -1,66 +1,66 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; - +import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.gem.BeanMappingGem; import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.source.ForgedMethod; -import org.mapstruct.ap.internal.model.source.ForgedMethodHistory; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.source.EnumMappingOptions; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; -import org.mapstruct.ap.internal.model.source.ValueMapping; -import org.mapstruct.ap.internal.prism.BeanMappingPrism; -import org.mapstruct.ap.internal.prism.MappingConstantsPrism; +import org.mapstruct.ap.internal.model.source.ValueMappingOptions; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.ap.internal.version.VersionInformation; +import org.mapstruct.ap.spi.EnumTransformationStrategy; + +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_REMAINING; +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_UNMAPPED; +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.NULL; +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.THROW_EXCEPTION; +import static org.mapstruct.ap.internal.util.Collections.first; /** * A {@link ValueMappingMethod} which maps one value type to another, optionally configured by one or more - * {@link ValueMapping}s. For now, only enum-to-enum mapping is supported. + * {@link ValueMappingOptions}s. For now, only enum-to-enum mapping is supported. * * @author Sjaak Derksen */ public class ValueMappingMethod extends MappingMethod { + private final List annotations; private final List valueMappings; - private final String defaultTarget; - private final String nullTarget; - private final boolean throwIllegalArgumentException; + private final MappingEntry defaultTarget; + private final MappingEntry nullTarget; + private final VersionInformation versionInformation; + + private final Type unexpectedValueMappingException; + private final boolean overridden; public static class Builder { private Method method; private MappingBuilderContext ctx; - private final List trueValueMappings = new ArrayList(); - private ValueMapping defaultTargetValue = null; - private ValueMapping nullTargetValue = null; - private boolean applyNamebasedMappings = true; + private ValueMappings valueMappings; + private EnumMappingOptions enumMapping; + private EnumTransformationStrategyInvoker enumTransformationInvoker; + private boolean enumTransformationIllegalReported = false; public Builder mappingContext(MappingBuilderContext mappingContext) { this.ctx = mappingContext; @@ -72,110 +72,196 @@ public Builder method(Method sourceMethod) { return this; } - public Builder valueMappings(List valueMappings) { - for ( ValueMapping valueMapping : valueMappings ) { - if ( MappingConstantsPrism.ANY_REMAINING.equals( valueMapping.getSource() ) ) { - defaultTargetValue = valueMapping; - } - else if ( MappingConstantsPrism.ANY_UNMAPPED.equals( valueMapping.getSource() ) ) { - defaultTargetValue = valueMapping; - applyNamebasedMappings = false; - } - else if ( MappingConstantsPrism.NULL.equals( valueMapping.getSource() ) ) { - nullTargetValue = valueMapping; - } - else { - trueValueMappings.add( valueMapping ); - } - } + public Builder valueMappings(List valueMappings) { + this.valueMappings = new ValueMappings( valueMappings ); return this; } - public ValueMappingMethod build( ) { + public Builder enumMapping(EnumMappingOptions enumMapping) { + this.enumMapping = enumMapping; + return this; + } + + public ValueMappingMethod build() { + + if ( !enumMapping.isValid() ) { + return null; + } + + initializeEnumTransformationStrategy(); // initialize all relevant parameters - List mappingEntries = new ArrayList(); - String nullTarget = null; - String defaultTarget = null; - boolean throwIllegalArgumentException = false; - - // for now, we're only dealing with enum mappings, populate relevant parameters based on enum-2-enum - if ( first( method.getSourceParameters() ).getType().isEnumType() && method.getResultType().isEnumType() ) { - mappingEntries.addAll( enumToEnumMapping( method ) ); - - if ( (nullTargetValue != null) && !MappingConstantsPrism.NULL.equals( nullTargetValue.getTarget() ) ) { - // absense nulltargetvalue reverts to null. Or it could be a deliberate choice to return null - nullTarget = nullTargetValue.getTarget(); - } - if ( defaultTargetValue != null ) { - // If the default target value is NULL then we should map it to null - defaultTarget = MappingConstantsPrism.NULL.equals( defaultTargetValue.getTarget() ) ? null : - defaultTargetValue.getTarget(); - } - else { - throwIllegalArgumentException = true; - } + List mappingEntries = new ArrayList<>(); + Type sourceType = first( method.getSourceParameters() ).getType(); + Type targetType = method.getResultType(); + + if ( targetType.isEnumType() && valueMappings.nullTarget == null ) { + // If null target is not set it means that the user has not explicitly defined a mapping for null + valueMappings.nullValueTarget = ctx.getEnumMappingStrategy() + .getDefaultNullEnumConstant( targetType.getTypeElement() ); + } + + // enum-to-enum + if ( sourceType.isEnumType() && targetType.isEnumType() ) { + mappingEntries.addAll( enumToEnumMapping( method, sourceType, targetType ) ); + } + else if ( sourceType.isEnumType() && targetType.isString() ) { + mappingEntries.addAll( enumToStringMapping( method, sourceType ) ); + } + else if ( sourceType.isString() && targetType.isEnumType() ) { + mappingEntries.addAll( stringToEnumMapping( method, targetType ) ); } // do before / after lifecycle mappings SelectionParameters selectionParameters = getSelectionParameters( method, ctx.getTypeUtils() ); - Set existingVariables = new HashSet( method.getParameterNames() ); + Set existingVariables = new HashSet<>( method.getParameterNames() ); List beforeMappingMethods = LifecycleMethodResolver.beforeMappingMethods( method, selectionParameters, ctx, existingVariables ); List afterMappingMethods = LifecycleMethodResolver.afterMappingMethods( method, selectionParameters, ctx, existingVariables ); + List annotations; + if ( method instanceof ForgedMethod ) { + annotations = Collections.emptyList(); + } + else { + annotations = new ArrayList<>(); + AdditionalAnnotationsBuilder additionalAnnotationsBuilder = + new AdditionalAnnotationsBuilder( + ctx.getElementUtils(), + ctx.getTypeFactory(), + ctx.getMessager() + ); + annotations.addAll( additionalAnnotationsBuilder.getProcessedAnnotations( method.getExecutable() ) ); + } // finally return a mapping - return new ValueMappingMethod( method, mappingEntries, nullTarget, defaultTarget, - throwIllegalArgumentException, beforeMappingMethods, afterMappingMethods ); + return new ValueMappingMethod( + method, + annotations, + mappingEntries, + valueMappings.nullValueTarget, + valueMappings.defaultTargetValue, + determineUnexpectedValueMappingException(), + beforeMappingMethods, + afterMappingMethods, + ctx.getVersionInformation() + ); } - private List enumToEnumMapping(Method method) { + private void initializeEnumTransformationStrategy() { + if ( !enumMapping.hasNameTransformationStrategy() ) { + enumTransformationInvoker = EnumTransformationStrategyInvoker.DEFAULT; + } + else { + Map enumTransformationStrategies = + ctx.getEnumTransformationStrategies(); + + String nameTransformationStrategy = enumMapping.getNameTransformationStrategy(); + if ( enumTransformationStrategies.containsKey( nameTransformationStrategy ) ) { + enumTransformationInvoker = new EnumTransformationStrategyInvoker( + enumTransformationStrategies.get( + nameTransformationStrategy ), enumMapping.getNameTransformationConfiguration() + ); + } + } - List mappings = new ArrayList(); - List unmappedSourceConstants - = new ArrayList( first( method.getSourceParameters() ).getType().getEnumConstants() ); + } + private String transform(String source) { + try { + return enumTransformationInvoker.transform( source ); + } + catch ( IllegalArgumentException ex ) { + if ( !enumTransformationIllegalReported ) { + enumTransformationIllegalReported = true; + ctx.getMessager().printMessage( + method.getExecutable(), + enumMapping.getMirror(), + Message.ENUMMAPPING_ILLEGAL_TRANSFORMATION, + enumTransformationInvoker.transformationStrategy.getStrategyName(), + ex.getMessage() + ); + } + return source; + } + } - if ( !reportErrorIfMappedEnumConstantsDontExist( method ) ) { + private List enumToEnumMapping(Method method, Type sourceType, Type targetType) { + + List mappings = new ArrayList<>(); + List unmappedSourceConstants = new ArrayList<>( sourceType.getEnumConstants() ); + boolean sourceErrorOccurred = reportErrorIfMappedSourceEnumConstantsDontExist( method, sourceType ); + boolean targetErrorOccurred = reportErrorIfMappedTargetEnumConstantsDontExist( method, targetType ); + if ( sourceErrorOccurred || targetErrorOccurred ) { return mappings; } - // Start to fill the mappings with the defined valuemappings - for ( ValueMapping valueMapping : trueValueMappings ) { - String target = - MappingConstantsPrism.NULL.equals( valueMapping.getTarget() ) ? null : valueMapping.getTarget(); - mappings.add( new MappingEntry( valueMapping.getSource(), target ) ); + // Start to fill the mappings with the defined value mappings + for ( ValueMappingOptions valueMapping : valueMappings.regularValueMappings ) { + mappings.add( new MappingEntry( valueMapping.getSource(), valueMapping.getTarget() ) ); unmappedSourceConstants.remove( valueMapping.getSource() ); } - // add mappings based on name - if ( applyNamebasedMappings ) { + if ( !valueMappings.hasMapAnyUnmapped ) { + + // We store the target constants in a map in order to support inherited inverse mapping + // When using a nameTransformationStrategy the transformation should be done on the target enum + // instead of the source enum + Map targetConstants = new LinkedHashMap<>(); + + boolean enumMappingInverse = enumMapping.isInverse(); + TypeElement targetTypeElement = method.getReturnType().getTypeElement(); + for ( String targetEnumConstant : method.getReturnType().getEnumConstants() ) { + String targetNameEnum = getEnumConstant( targetTypeElement, targetEnumConstant ); + if ( enumMappingInverse ) { + // If the mapping is inverse we have to change the target enum constant + targetConstants.put( + transform( targetNameEnum ), + targetEnumConstant + ); + } + else { + targetConstants.put( targetNameEnum, targetEnumConstant ); + } + } + + TypeElement sourceTypeElement = sourceType.getTypeElement(); + for ( String sourceConstant : new ArrayList<>( unmappedSourceConstants ) ) { + String sourceNameConstant = getEnumConstant( sourceTypeElement, sourceConstant ); + String targetConstant; + if ( !enumMappingInverse ) { + targetConstant = transform( sourceNameConstant ); + } + else { + targetConstant = sourceNameConstant; + } - // get all target constants - List targetConstants = method.getReturnType().getEnumConstants(); - for ( String sourceConstant : new ArrayList( unmappedSourceConstants ) ) { - if ( targetConstants.contains( sourceConstant ) ) { - mappings.add( new MappingEntry( sourceConstant, sourceConstant ) ); + if ( targetConstants.containsKey( targetConstant ) ) { + mappings.add( new MappingEntry( sourceConstant, targetConstants.get( targetConstant ) ) ); + unmappedSourceConstants.remove( sourceConstant ); + } + else if ( NULL.equals( targetConstant ) ) { + mappings.add( new MappingEntry( sourceConstant, null ) ); unmappedSourceConstants.remove( sourceConstant ); } } - if ( defaultTargetValue == null && !unmappedSourceConstants.isEmpty() ) { + if ( valueMappings.defaultTarget == null && !unmappedSourceConstants.isEmpty() ) { String sourceErrorMessage = "source"; String targetErrorMessage = "target"; if ( method instanceof ForgedMethod && ( (ForgedMethod) method ).getHistory() != null ) { ForgedMethodHistory history = ( (ForgedMethod) method ).getHistory(); sourceErrorMessage = history.createSourcePropertyErrorMessage(); targetErrorMessage = - "\"" + history.getTargetType().toString() + " " + history.createTargetPropertyName() + "\""; + "\"" + history.getTargetType().describe() + " " + history.createTargetPropertyName() + "\""; } // all sources should now be matched, there's no default to fall back to, so if sources remain, // we have an issue. - ctx.getMessager().printMessage( method.getExecutable(), - Message.VALUE_MAPPING_UNMAPPED_SOURCES, + ctx.getMessager().printMessage( + method.getExecutable(), + Message.VALUEMAPPING_UNMAPPED_SOURCES, sourceErrorMessage, targetErrorMessage, Strings.join( unmappedSourceConstants, ", " ) @@ -186,38 +272,154 @@ private List enumToEnumMapping(Method method) { return mappings; } - private SelectionParameters getSelectionParameters(Method method, Types typeUtils) { - BeanMappingPrism beanMappingPrism = BeanMappingPrism.getInstanceOn( method.getExecutable() ); - if ( beanMappingPrism != null ) { - List qualifiers = beanMappingPrism.qualifiedBy(); - List qualifyingNames = beanMappingPrism.qualifiedByName(); - TypeMirror resultType = beanMappingPrism.resultType(); + private List enumToStringMapping(Method method, Type sourceType) { + + List mappings = new ArrayList<>(); + List unmappedSourceConstants = new ArrayList<>( sourceType.getEnumConstants() ); + boolean sourceErrorOccurred = reportErrorIfMappedSourceEnumConstantsDontExist( method, sourceType ); + boolean anyRemainingUsedError = reportErrorIfSourceEnumConstantsContainsAnyRemaining( method ); + if ( sourceErrorOccurred || anyRemainingUsedError ) { + return mappings; + } + + // Start to fill the mappings with the defined valueMappings + for ( ValueMappingOptions valueMapping : valueMappings.regularValueMappings ) { + mappings.add( new MappingEntry( valueMapping.getSource(), valueMapping.getTarget() ) ); + unmappedSourceConstants.remove( valueMapping.getSource() ); + } + + // add mappings based on name + if ( !valueMappings.hasMapAnyUnmapped ) { + + TypeElement sourceTypeElement = sourceType.getTypeElement(); + // all remaining constants are mapped + for ( String sourceConstant : unmappedSourceConstants ) { + String sourceNameConstant = getEnumConstant( sourceTypeElement, sourceConstant ); + String targetConstant = transform( sourceNameConstant ); + mappings.add( new MappingEntry( sourceConstant, targetConstant ) ); + } + } + return mappings; + } + + private List stringToEnumMapping(Method method, Type targetType) { + + List mappings = new ArrayList<>(); + List unmappedSourceConstants = new ArrayList<>( targetType.getEnumConstants() ); + boolean sourceErrorOccurred = reportErrorIfMappedTargetEnumConstantsDontExist( method, targetType ); + reportWarningIfAnyRemainingOrAnyUnMappedMissing( method ); + if ( sourceErrorOccurred ) { + return mappings; + } + Set mappedSources = new LinkedHashSet<>(); + + // Start to fill the mappings with the defined value mappings + for ( ValueMappingOptions valueMapping : valueMappings.regularValueMappings ) { + mappedSources.add( valueMapping.getSource() ); + mappings.add( new MappingEntry( valueMapping.getSource(), valueMapping.getTarget() ) ); + unmappedSourceConstants.remove( valueMapping.getSource() ); + } + + // add mappings based on name + if ( !valueMappings.hasMapAnyUnmapped ) { + mappedSources.add( NULL ); + TypeElement targetTypeElement = targetType.getTypeElement(); + // all remaining constants are mapped + for ( String sourceConstant : unmappedSourceConstants ) { + String sourceNameConstant = getEnumConstant( targetTypeElement, sourceConstant ); + String stringConstant = transform( sourceNameConstant ); + if ( !mappedSources.contains( stringConstant ) ) { + mappings.add( new MappingEntry( stringConstant, sourceConstant ) ); + } + } + } + return mappings; + } + + private String getEnumConstant(TypeElement typeElement, String enumConstant) { + return ctx.getEnumMappingStrategy().getEnumConstant( typeElement, enumConstant ); + } + + private SelectionParameters getSelectionParameters(Method method, TypeUtils typeUtils) { + BeanMappingGem beanMapping = BeanMappingGem.instanceOn( method.getExecutable() ); + if ( beanMapping != null ) { + List qualifiers = beanMapping.qualifiedBy().get(); + List qualifyingNames = beanMapping.qualifiedByName().get(); + TypeMirror resultType = beanMapping.resultType().get(); return new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); } return null; } - private boolean reportErrorIfMappedEnumConstantsDontExist(Method method) { - List sourceEnumConstants = first( method.getSourceParameters() ).getType().getEnumConstants(); - List targetEnumConstants = method.getReturnType().getEnumConstants(); + private boolean reportErrorIfMappedSourceEnumConstantsDontExist(Method method, Type sourceType) { + List sourceEnumConstants = sourceType.getEnumConstants(); boolean foundIncorrectMapping = false; - for ( ValueMapping mappedConstant : trueValueMappings ) { + for ( ValueMappingOptions mappedConstant : valueMappings.regularValueMappings ) { + + if ( !enumMapping.isInverse() && THROW_EXCEPTION.equals( mappedConstant.getSource() ) ) { + ctx.getMessager().printMessage( + method.getExecutable(), + mappedConstant.getMirror(), + mappedConstant.getSourceAnnotationValue(), + Message.VALUEMAPPING_THROW_EXCEPTION_SOURCE + ); + foundIncorrectMapping = true; + } + else if ( !sourceEnumConstants.contains( mappedConstant.getSource() ) ) { - if ( !sourceEnumConstants.contains( mappedConstant.getSource() ) ) { - ctx.getMessager().printMessage( method.getExecutable(), + ctx.getMessager().printMessage( + method.getExecutable(), mappedConstant.getMirror(), mappedConstant.getSourceAnnotationValue(), Message.VALUEMAPPING_NON_EXISTING_CONSTANT, mappedConstant.getSource(), - first( method.getSourceParameters() ).getType() + sourceType ); foundIncorrectMapping = true; } - if ( !MappingConstantsPrism.NULL.equals( mappedConstant.getTarget() ) + } + return foundIncorrectMapping; + } + + private boolean reportErrorIfSourceEnumConstantsContainsAnyRemaining(Method method) { + boolean foundIncorrectMapping = false; + + if ( valueMappings.hasMapAnyRemaining ) { + ctx.getMessager().printMessage( + method.getExecutable(), + valueMappings.defaultTarget.getMirror(), + valueMappings.defaultTarget.getSourceAnnotationValue(), + Message.VALUEMAPPING_ANY_REMAINING_FOR_NON_ENUM, + method.getResultType() + ); + foundIncorrectMapping = true; + } + return foundIncorrectMapping; + } + + private void reportWarningIfAnyRemainingOrAnyUnMappedMissing(Method method) { + + if ( !( valueMappings.hasMapAnyUnmapped || valueMappings.hasMapAnyRemaining ) ) { + ctx.getMessager().printMessage( + method.getExecutable(), + Message.VALUEMAPPING_ANY_REMAINING_OR_UNMAPPED_MISSING + ); + } + } + + private boolean reportErrorIfMappedTargetEnumConstantsDontExist(Method method, Type targetType) { + List targetEnumConstants = targetType.getEnumConstants(); + + boolean foundIncorrectMapping = false; + + for ( ValueMappingOptions mappedConstant : valueMappings.regularValueMappings ) { + if ( !NULL.equals( mappedConstant.getTarget() ) + && !THROW_EXCEPTION.equals( mappedConstant.getTarget() ) && !targetEnumConstants.contains( mappedConstant.getTarget() ) ) { - ctx.getMessager().printMessage( method.getExecutable(), + ctx.getMessager().printMessage( + method.getExecutable(), mappedConstant.getMirror(), mappedConstant.getTargetAnnotationValue(), Message.VALUEMAPPING_NON_EXISTING_CONSTANT, @@ -228,59 +430,205 @@ private boolean reportErrorIfMappedEnumConstantsDontExist(Method method) { } } - if ( defaultTargetValue != null && !MappingConstantsPrism.NULL.equals( defaultTargetValue.getTarget() ) - && !targetEnumConstants.contains( defaultTargetValue.getTarget() ) ) { - ctx.getMessager().printMessage( method.getExecutable(), - defaultTargetValue.getMirror(), - defaultTargetValue.getTargetAnnotationValue(), + if ( valueMappings.defaultTarget != null + && !THROW_EXCEPTION.equals( valueMappings.defaultTarget.getTarget() ) + && !NULL.equals( valueMappings.defaultTarget.getTarget() ) + && !targetEnumConstants.contains( valueMappings.defaultTarget.getTarget() ) ) { + ctx.getMessager().printMessage( + method.getExecutable(), + valueMappings.defaultTarget.getMirror(), + valueMappings.defaultTarget.getTargetAnnotationValue(), Message.VALUEMAPPING_NON_EXISTING_CONSTANT, - defaultTargetValue.getTarget(), + valueMappings.defaultTarget.getTarget(), method.getReturnType() ); foundIncorrectMapping = true; } - if ( nullTargetValue != null && MappingConstantsPrism.NULL.equals( nullTargetValue.getTarget() ) - && !targetEnumConstants.contains( nullTargetValue.getTarget() ) ) { - ctx.getMessager().printMessage( method.getExecutable(), - nullTargetValue.getMirror(), - nullTargetValue.getTargetAnnotationValue(), + if ( valueMappings.nullTarget != null && NULL.equals( valueMappings.nullTarget.getTarget() ) + && !targetEnumConstants.contains( valueMappings.nullTarget.getTarget() ) ) { + ctx.getMessager().printMessage( + method.getExecutable(), + valueMappings.nullTarget.getMirror(), + valueMappings.nullTarget.getTargetAnnotationValue(), Message.VALUEMAPPING_NON_EXISTING_CONSTANT, - nullTargetValue.getTarget(), + valueMappings.nullTarget.getTarget(), method.getReturnType() ); foundIncorrectMapping = true; } + else if ( valueMappings.nullTarget == null && valueMappings.nullValueTarget != null + && !valueMappings.nullValueTarget.equals( THROW_EXCEPTION ) + && !targetEnumConstants.contains( valueMappings.nullValueTarget ) ) { + // if there is no nullTarget, but nullValueTarget has a value it means that there was an SPI + // which returned an enum for the target enum + ctx.getMessager().printMessage( + method.getExecutable(), + Message.VALUEMAPPING_NON_EXISTING_CONSTANT_FROM_SPI, + valueMappings.nullValueTarget, + method.getReturnType(), + ctx.getEnumMappingStrategy() + ); + } + + return foundIncorrectMapping; + } + + private Type determineUnexpectedValueMappingException() { + TypeMirror unexpectedValueMappingException = enumMapping.getUnexpectedValueMappingException(); + if ( unexpectedValueMappingException != null ) { + return ctx.getTypeFactory().getType( unexpectedValueMappingException ); + } - return !foundIncorrectMapping; + return ctx.getTypeFactory() + .getType( ctx.getEnumMappingStrategy().getUnexpectedValueMappingExceptionType() ); } } - private ValueMappingMethod(Method method, List enumMappings, String nullTarget, String defaultTarget, - boolean throwIllegalArgumentException, List beforeMappingMethods, - List afterMappingMethods) { + private static class EnumTransformationStrategyInvoker { + + private static final EnumTransformationStrategyInvoker DEFAULT = new EnumTransformationStrategyInvoker( + null, + null + ); + + private final EnumTransformationStrategy transformationStrategy; + private final String configuration; + + private EnumTransformationStrategyInvoker( + EnumTransformationStrategy transformationStrategy, String configuration) { + this.transformationStrategy = transformationStrategy; + this.configuration = configuration; + } + + private String transform(String source) { + if ( transformationStrategy == null ) { + return source; + } + + return transformationStrategy.transform( source, configuration ); + } + } + + private static class ValueMappings { + + List regularValueMappings = new ArrayList<>(); + ValueMappingOptions defaultTarget = null; + String defaultTargetValue = null; + ValueMappingOptions nullTarget = null; + String nullValueTarget = null; + boolean hasMapAnyUnmapped = false; + boolean hasMapAnyRemaining = false; + boolean hasDefaultValue = false; + boolean hasAtLeastOneExceptionValue = false; + + ValueMappings(List valueMappings) { + + for ( ValueMappingOptions valueMapping : valueMappings ) { + if ( ANY_REMAINING.equals( valueMapping.getSource() ) ) { + defaultTarget = valueMapping; + defaultTargetValue = defaultTarget.getTarget(); + hasDefaultValue = true; + hasMapAnyRemaining = true; + } + else if ( ANY_UNMAPPED.equals( valueMapping.getSource() ) ) { + defaultTarget = valueMapping; + defaultTargetValue = defaultTarget.getTarget(); + hasDefaultValue = true; + hasMapAnyUnmapped = true; + } + else if ( NULL.equals( valueMapping.getSource() ) ) { + nullTarget = valueMapping; + nullValueTarget = getValue( nullTarget ); + } + else { + regularValueMappings.add( valueMapping ); + } + + if ( THROW_EXCEPTION.equals( valueMapping.getTarget() ) ) { + hasAtLeastOneExceptionValue = true; + } + } + } + + String getValue(ValueMappingOptions valueMapping) { + return NULL.equals( valueMapping.getTarget() ) ? null : valueMapping.getTarget(); + } + } + + private ValueMappingMethod(Method method, + List annotations, + List enumMappings, + String nullTarget, + String defaultTarget, + Type unexpectedValueMappingException, + List beforeMappingMethods, + List afterMappingMethods, + VersionInformation versionInformation) { super( method, beforeMappingMethods, afterMappingMethods ); this.valueMappings = enumMappings; - this.nullTarget = nullTarget; - this.defaultTarget = defaultTarget; - this.throwIllegalArgumentException = throwIllegalArgumentException; + this.nullTarget = new MappingEntry( null, nullTarget ); + this.defaultTarget = new MappingEntry( null, defaultTarget != null ? defaultTarget : THROW_EXCEPTION ); + this.unexpectedValueMappingException = unexpectedValueMappingException; this.overridden = method.overridesMethod(); + this.annotations = annotations; + this.versionInformation = versionInformation; + } + + public boolean isDefaultTargetRequired() { + if ( !versionInformation.isSourceVersionAtLeast14() ) { + return true; + } + + Type sourceType = getSourceParameter().getType(); + if ( !sourceType.isEnumType() ) { + return true; + } + + return sourceType.getEnumConstants().size() != getValueMappings().size(); + } + + @Override + public Set getImportTypes() { + Set importTypes = super.getImportTypes(); + + if ( unexpectedValueMappingException != null && !unexpectedValueMappingException.isJavaLangType() ) { + if ( ( isDefaultTargetRequired() && defaultTarget.isTargetAsException() ) || + nullTarget.isTargetAsException() || + hasMappingWithTargetAsException() ) { + importTypes.addAll( unexpectedValueMappingException.getImportTypes() ); + } + } + for ( Annotation annotation : annotations ) { + importTypes.addAll( annotation.getImportTypes() ); + } + return importTypes; + } + + protected boolean hasMappingWithTargetAsException() { + return getValueMappings() + .stream() + .anyMatch( MappingEntry::isTargetAsException ); } public List getValueMappings() { return valueMappings; } - public String getDefaultTarget() { + public MappingEntry getDefaultTarget() { return defaultTarget; } - public String getNullTarget() { + public MappingEntry getNullTarget() { return nullTarget; } - public boolean isThrowIllegalArgumentException() { - return throwIllegalArgumentException; + public VersionInformation getVersionInformation() { + return versionInformation; + } + + public Type getUnexpectedValueMappingException() { + return unexpectedValueMappingException; } public Parameter getSourceParameter() { @@ -291,13 +639,30 @@ public boolean isOverridden() { return overridden; } + public List getAnnotations() { + return annotations; + } + public static class MappingEntry { private final String source; private final String target; + private boolean targetAsException = false; - MappingEntry( String source, String target ) { + MappingEntry(String source, String target) { this.source = source; - this.target = target; + if ( !NULL.equals( target ) ) { + this.target = target; + if ( THROW_EXCEPTION.equals( target ) ) { + this.targetAsException = true; + } + } + else { + this.target = null; + } + } + + public boolean isTargetAsException() { + return targetAsException; } public String getSource() { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/VirtualMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/VirtualMappingMethod.java deleted file mode 100644 index dbaec580e7..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/VirtualMappingMethod.java +++ /dev/null @@ -1,112 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model; - -import java.util.Set; - -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod; - -/** - * A mapping method which is not based on an actual method declared in the original mapper interface but is added as - * private method to map a certain source/target type combination. Based on a {@link BuiltInMethod}. - * - * @author Gunnar Morling - */ -public class VirtualMappingMethod extends MappingMethod { - - private final String templateName; - private final Set importTypes; - - public VirtualMappingMethod(BuiltInMethod method) { - super( method ); - this.importTypes = method.getImportTypes(); - this.templateName = getTemplateNameForClass( method.getClass() ); - } - - public VirtualMappingMethod(HelperMethod method) { - super( method ); - this.importTypes = method.getImportTypes(); - this.templateName = getTemplateNameForClass( method.getClass() ); - } - - @Override - public String getTemplateName() { - return templateName; - } - - @Override - public Set getImportTypes() { - return importTypes; - } - - /** - * Finds a {@link Type} by a given name. The {@code name} will be compared to the fully-qualified and also simple - * names of the {@code importTypes}. - * - * @param name Fully-qualified or simple name of the type. - * - * @return Found type, never null. - * - * @throws IllegalArgumentException In case no {@link Type} was found for given name. - */ - public Type findType(String name) { - for ( Type type : importTypes ) { - if ( type.getFullyQualifiedName().contentEquals( name ) ) { - return type; - } - if ( type.getName().contentEquals( name ) ) { - return type; - } - } - - throw new IllegalArgumentException( "No type for given name '" + name + "' found in 'importTypes'." ); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ( ( templateName == null ) ? 0 : templateName.hashCode() ); - return result; - } - - @Override - public boolean equals(Object obj) { - if ( this == obj ) { - return true; - } - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - VirtualMappingMethod other = (VirtualMappingMethod) obj; - if ( templateName == null ) { - if ( other.templateName != null ) { - return false; - } - } - else if ( !templateName.equals( other.templateName ) ) { - return false; - } - return true; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/annotation/AnnotationElement.java b/processor/src/main/java/org/mapstruct/ap/internal/model/annotation/AnnotationElement.java new file mode 100644 index 0000000000..f242b51f47 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/annotation/AnnotationElement.java @@ -0,0 +1,130 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.annotation; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * Represents an annotation element. + * + * @author Ben Zegveld + */ +public class AnnotationElement extends ModelElement { + public enum AnnotationElementType { + BOOLEAN, BYTE, CHARACTER, CLASS, DOUBLE, ENUM, FLOAT, INTEGER, LONG, SHORT, STRING + } + + private final String elementName; + private final List values; + private final AnnotationElementType type; + + public AnnotationElement(AnnotationElementType type, List values) { + this( type, null, values ); + } + + public AnnotationElement(AnnotationElementType type, String elementName, List values) { + this.type = type; + this.elementName = elementName; + this.values = values; + } + + public String getElementName() { + return elementName; + } + + public List getValues() { + return values; + } + + @Override + public Set getImportTypes() { + Set importTypes = null; + for ( Object value : values ) { + if ( value instanceof ModelElement ) { + if ( importTypes == null ) { + importTypes = new HashSet<>(); + } + importTypes.addAll( ( (ModelElement) value ).getImportTypes() ); + } + } + + return importTypes == null ? Collections.emptySet() : importTypes; + } + + public boolean isBoolean() { + return type == AnnotationElementType.BOOLEAN; + } + + public boolean isByte() { + return type == AnnotationElementType.BYTE; + } + + public boolean isCharacter() { + return type == AnnotationElementType.CHARACTER; + } + + public boolean isClass() { + return type == AnnotationElementType.CLASS; + } + + public boolean isDouble() { + return type == AnnotationElementType.DOUBLE; + } + + public boolean isEnum() { + return type == AnnotationElementType.ENUM; + } + + public boolean isFloat() { + return type == AnnotationElementType.FLOAT; + } + + public boolean isInteger() { + return type == AnnotationElementType.INTEGER; + } + + public boolean isLong() { + return type == AnnotationElementType.LONG; + } + + public boolean isShort() { + return type == AnnotationElementType.SHORT; + } + + public boolean isString() { + return type == AnnotationElementType.STRING; + } + + @Override + public int hashCode() { + return Objects.hash( elementName, type, values ); + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + AnnotationElement other = (AnnotationElement) obj; + return Objects.equals( elementName, other.elementName ) + && type == other.type + && Objects.equals( values, other.values ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/annotation/EnumAnnotationElementHolder.java b/processor/src/main/java/org/mapstruct/ap/internal/model/annotation/EnumAnnotationElementHolder.java new file mode 100644 index 0000000000..de87f32525 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/annotation/EnumAnnotationElementHolder.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.annotation; + +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.Type; + +public class EnumAnnotationElementHolder extends ModelElement { + + private final Type enumClass; + private final String name; + + public EnumAnnotationElementHolder(Type enumClass, String name) { + this.enumClass = enumClass; + this.name = name; + } + + public Type getEnumClass() { + return enumClass; + } + + public String getName() { + return name; + } + + @Override + public Set getImportTypes() { + return enumClass.getImportTypes(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AdderWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AdderWrapper.java index d7e9322d4c..13dfe832c9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AdderWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AdderWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -43,18 +30,30 @@ public class AdderWrapper extends AssignmentWrapper { public AdderWrapper( Assignment rhs, List thrownTypesToExclude, boolean fieldAssignment, - String targetPropertyName ) { + String adderIteratorName ) { super( rhs, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; - String desiredName = Nouns.singularize( targetPropertyName ); - rhs.setSourceLocalVarName( rhs.createLocalVarName( desiredName ) ); - adderType = first( getSourceType().determineTypeArguments( Collection.class ) ); + // a method local var has been added earlier. + + + // localVar is iteratorVariable + String desiredName = Nouns.singularize( adderIteratorName ); + rhs.setSourceLoopVarName( rhs.createUniqueVarName( desiredName ) ); + if ( getSourceType().isCollectionType() ) { + adderType = first( getSourceType().determineTypeArguments( Collection.class ) ); + } + else if ( getSourceType().isArrayType() ) { + adderType = getSourceType().getComponentType(); + } + else { // iterable + adderType = first( getSourceType().determineTypeArguments( Iterable.class ) ); + } } @Override public List getThrownTypes() { List parentThrownTypes = super.getThrownTypes(); - List result = new ArrayList( parentThrownTypes ); + List result = new ArrayList<>( parentThrownTypes ); for ( Type thrownTypeToExclude : thrownTypesToExclude ) { for ( Type parentExceptionType : parentThrownTypes ) { if ( parentExceptionType.isAssignableTo( thrownTypeToExclude ) ) { @@ -69,10 +68,21 @@ public Type getAdderType() { return adderType; } + public boolean isIncludeSourceNullCheck() { + return true; + } + + public boolean isSetExplicitlyToNull() { + return false; + } + + public boolean isSetExplicitlyToDefault() { + return false; + } + @Override public Set getImportTypes() { - Set imported = new HashSet(); - imported.addAll( super.getImportTypes() ); + Set imported = new HashSet<>( super.getImportTypes() ); imported.add( adderType.getTypeBound() ); return imported; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java index 2dfc5b6cd8..6b623f7e39 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -33,22 +20,27 @@ public class ArrayCopyWrapper extends AssignmentWrapper { private final Type arraysType; private final Type targetType; + private final boolean setExplicitlyToNull; + private final boolean setExplicitlyToDefault; public ArrayCopyWrapper(Assignment rhs, String targetPropertyName, Type arraysType, Type targetType, - boolean fieldAssignment) { + boolean fieldAssignment, + boolean setExplicitlyToNull, + boolean setExplicitlyToDefault) { super( rhs, fieldAssignment ); this.arraysType = arraysType; this.targetType = targetType; - rhs.setSourceLocalVarName( rhs.createLocalVarName( targetPropertyName ) ); + rhs.setSourceLocalVarName( rhs.createUniqueVarName( targetPropertyName ) ); + this.setExplicitlyToDefault = setExplicitlyToDefault; + this.setExplicitlyToNull = setExplicitlyToNull; } @Override public Set getImportTypes() { - Set imported = new HashSet(); - imported.addAll( getAssignment().getImportTypes() ); + Set imported = new HashSet<>( getAssignment().getImportTypes() ); imported.add( arraysType ); imported.add( targetType ); return imported; @@ -57,4 +49,12 @@ public Set getImportTypes() { public boolean isIncludeSourceNullCheck() { return true; } + + public boolean isSetExplicitlyToNull() { + return setExplicitlyToNull; + } + + public boolean isSetExplicitlyToDefault() { + return setExplicitlyToDefault; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AssignmentWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AssignmentWrapper.java index 6bcdb93ff8..54885012a9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AssignmentWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/AssignmentWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -23,6 +10,7 @@ import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; import org.mapstruct.ap.internal.model.common.Type; /** @@ -70,7 +58,7 @@ public boolean isSourceReferenceParameter() { } @Override - public String getSourcePresenceCheckerReference() { + public PresenceCheck getSourcePresenceCheckerReference() { return decoratedAssignment.getSourcePresenceCheckerReference(); } @@ -89,6 +77,16 @@ public void setSourceLocalVarName(String sourceLocalVarName) { decoratedAssignment.setSourceLocalVarName( sourceLocalVarName ); } + @Override + public String getSourceLoopVarName() { + return decoratedAssignment.getSourceLoopVarName(); + } + + @Override + public void setSourceLoopVarName(String sourceLoopVarName) { + decoratedAssignment.setSourceLoopVarName( sourceLoopVarName ); + } + @Override public String getSourceParameterName() { return decoratedAssignment.getSourceParameterName(); @@ -105,8 +103,8 @@ public boolean isCallingUpdateMethod() { } @Override - public String createLocalVarName( String desiredName ) { - return decoratedAssignment.createLocalVarName( desiredName ); + public String createUniqueVarName(String desiredName ) { + return decoratedAssignment.createUniqueVarName( desiredName ); } /** @@ -116,4 +114,5 @@ public String createLocalVarName( String desiredName ) { public boolean isFieldAssignment() { return fieldAssignment; } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.java index 80d9e403c4..eaa2fe68ff 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -25,6 +12,7 @@ import org.mapstruct.ap.internal.model.common.Type; /** + * Decorates the assignment as an {@link Enum} constant access. * * @author Sjaak Derksen */ @@ -39,7 +27,7 @@ public EnumConstantWrapper(Assignment decoratedAssignment, Type enumType ) { @Override public Set getImportTypes() { - Set imported = new HashSet( getAssignment().getImportTypes() ); + Set imported = new HashSet<>( getAssignment().getImportTypes() ); imported.add( enumType ); return imported; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.java index 2326b144b5..ce347321c9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.java @@ -1,36 +1,27 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; -import static org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism.ALWAYS; - +import java.util.HashSet; import java.util.List; +import java.util.Set; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; + +import static org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem.ALWAYS; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.IGNORE; /** * This wrapper handles the situation where an assignment is done for an update method. * - * In case of a pre-existing target the wrapper checks if there is an collection or map initialized on the target bean + * In case of a pre-existing target the wrapper checks if there is a collection or map initialized on the target bean * (not null). If so it uses the addAll (for collections) or putAll (for maps). The collection / map is cleared in case * of a pre-existing target {@link org.mapstruct.MappingTarget }before adding the source entries. * @@ -42,28 +33,49 @@ public class ExistingInstanceSetterWrapperForCollectionsAndMaps extends SetterWrapperForCollectionsAndMapsWithNullCheck { - private final boolean includeSourceNullCheck; + private final NullValuePropertyMappingStrategyGem nvpms; + private final NullValueCheckStrategyGem nvcs; + private final Type targetType; public ExistingInstanceSetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment, List thrownTypesToExclude, Type targetType, - NullValueCheckStrategyPrism nvms, + NullValueCheckStrategyGem nvcs, + NullValuePropertyMappingStrategyGem nvpms, TypeFactory typeFactory, - boolean fieldAssignment, - boolean mapNullToDefault) { + boolean fieldAssignment) { super( decoratedAssignment, thrownTypesToExclude, targetType, typeFactory, - fieldAssignment, - mapNullToDefault + fieldAssignment ); - this.includeSourceNullCheck = ALWAYS == nvms; + this.nvcs = nvcs; + this.nvpms = nvpms; + this.targetType = targetType; + } + + @Override + public Set getImportTypes() { + Set imported = new HashSet<>( super.getImportTypes() ); + if ( isMapNullToDefault() && ( targetType.getImplementationType() != null ) ) { + imported.addAll( getNewInstance().getImportTypes() ); + } + return imported; + } + + public boolean isIncludeElseBranch() { + return nvcs != ALWAYS && nvpms != IGNORE; } - public boolean isIncludeSourceNullCheck() { - return includeSourceNullCheck; + public boolean isMapNullToDefault() { + return nvpms == NullValuePropertyMappingStrategyGem.SET_TO_DEFAULT; } + + public boolean isMapNullToClear() { + return nvpms == NullValuePropertyMappingStrategyGem.CLEAR; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.java index 2d0c2429a3..e1c0c8cb20 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -22,14 +9,17 @@ import java.util.List; import java.util.Set; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Type; +import static org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem.IGNORE; + /** * This wrapper handles the situation were an assignment must be done via a target getter method because there * is no setter available. * - * The wrapper checks if there is an collection or map initialized on the target bean (not null). If so it uses the + * The wrapper checks if there is a collection or map initialized on the target bean (not null). If so it uses the * addAll (for collections) or putAll (for maps). The collection / map is cleared in case of a pre-existing target * {@link org.mapstruct.MappingTarget }before adding the source entries. The goal is that the same collection / map * is used as target. @@ -39,6 +29,14 @@ * @author Sjaak Derksen */ public class GetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAndMaps { + private final boolean ignoreMapNull; + + public GetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment, + List thrownTypesToExclude, + Type targetType, + boolean fieldAssignment) { + this( decoratedAssignment, thrownTypesToExclude, targetType, null, fieldAssignment ); + } /** * @param decoratedAssignment source RHS @@ -49,6 +47,7 @@ public class GetterWrapperForCollectionsAndMaps extends WrapperForCollectionsAnd public GetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment, List thrownTypesToExclude, Type targetType, + NullValuePropertyMappingStrategyGem nvpms, boolean fieldAssignment) { super( @@ -57,14 +56,19 @@ public GetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment, targetType, fieldAssignment ); + this.ignoreMapNull = nvpms == IGNORE; } @Override public Set getImportTypes() { - Set imported = new HashSet( super.getImportTypes() ); + Set imported = new HashSet<>( super.getImportTypes() ); if ( getSourcePresenceCheckerReference() == null ) { imported.addAll( getNullCheckLocalVarType().getImportTypes() ); } return imported; } + + public boolean isIgnoreMapNull() { + return ignoreMapNull; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.java index 6d4a00e5f0..e629ae35f1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -44,7 +31,7 @@ public Java8FunctionWrapper(Assignment decoratedAssignment, Type functionType) { @Override public Set getImportTypes() { - Set imported = new HashSet( super.getImportTypes() ); + Set imported = new HashSet<>( super.getImportTypes() ); if ( isDirectAssignment() && functionType != null ) { imported.add( functionType ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.java index 8b28b331fa..1287ab6cd6 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -46,7 +33,7 @@ public LocalVarWrapper(Assignment decoratedAssignment, List thrownTypesToE @Override public List getThrownTypes() { List parentThrownTypes = super.getThrownTypes(); - List result = new ArrayList( parentThrownTypes ); + List result = new ArrayList<>( parentThrownTypes ); for ( Type thrownTypeToExclude : thrownTypesToExclude ) { for ( Type parentThrownType : parentThrownTypes ) { if ( parentThrownType.isAssignableTo( thrownTypeToExclude ) ) { @@ -59,7 +46,7 @@ public List getThrownTypes() { @Override public Set getImportTypes() { - Set imported = new HashSet( getAssignment().getImportTypes() ); + Set imported = new HashSet<>( getAssignment().getImportTypes() ); imported.add( targetType ); imported.addAll( targetType.getTypeParameters() ); return imported; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NewInstanceSetterWrapperForCollectionsAndMaps.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NewInstanceSetterWrapperForCollectionsAndMaps.java new file mode 100644 index 0000000000..f0e23470a7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/NewInstanceSetterWrapperForCollectionsAndMaps.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.assignment; + +import java.util.List; + +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; + +/** + * This wrapper handles the situation where an assignment is done via the setter, while creating the collection or map + * using a no-args constructor. + * + * @author Ben Zegveld + */ +public class NewInstanceSetterWrapperForCollectionsAndMaps extends SetterWrapperForCollectionsAndMapsWithNullCheck { + + private String instanceVar; + + public NewInstanceSetterWrapperForCollectionsAndMaps(Assignment decoratedAssignment, + List thrownTypesToExclude, + Type targetType, + TypeFactory typeFactory, + boolean fieldAssignment) { + + super( + decoratedAssignment, + thrownTypesToExclude, + targetType, + typeFactory, + fieldAssignment + ); + this.instanceVar = decoratedAssignment.createUniqueVarName( targetType.getName() ); + } + + public String getInstanceVar() { + return instanceVar; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/OptionalGetWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/OptionalGetWrapper.java new file mode 100644 index 0000000000..6c405c871d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/OptionalGetWrapper.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.assignment; + +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Strings; + +/** + * Decorates the assignment as an {@link java.util.Optional#get()} call. + * + * @author Filip Hrisafov + */ +public class OptionalGetWrapper extends AssignmentWrapper { + + private final Type optionalType; + + public OptionalGetWrapper(Assignment decoratedAssignment, Type optionalType) { + super( decoratedAssignment, false ); + this.optionalType = optionalType; + } + + public Type getOptionalType() { + return optionalType; + } + + @Override + public String toString() { + if ( optionalType.getFullyQualifiedName().equals( "java.util.Optional" ) ) { + return getAssignment() + ".get()"; + } + return getAssignment() + ".getAs" + Strings.capitalize( optionalType.getOptionalBaseType().getName() ) + "()"; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ReturnWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ReturnWrapper.java new file mode 100644 index 0000000000..76e2c19fa7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/ReturnWrapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.assignment; + +import org.mapstruct.ap.internal.model.common.Assignment; + +/** + * Decorates an assignment as a return variable. + * + * @author Ben Zegveld + */ +public class ReturnWrapper extends AssignmentWrapper { + + public ReturnWrapper(Assignment decoratedAssignment) { + super( decoratedAssignment, false ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java index 97ccc25f00..94b031c622 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapper.java @@ -1,31 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; - -import static org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism.ALWAYS; /** * Wraps the assignment in a target setter. @@ -36,28 +22,43 @@ public class SetterWrapper extends AssignmentWrapper { private final List thrownTypesToExclude; private final boolean includeSourceNullCheck; + private final boolean setExplicitlyToNull; + private final boolean setExplicitlyToDefault; + private final boolean mustCastForNull; + private final Type nullCastType; public SetterWrapper(Assignment rhs, List thrownTypesToExclude, - NullValueCheckStrategyPrism nvms, boolean fieldAssignment, - Type targetType) { + boolean includeSourceNullCheck, + boolean setExplicitlyToNull, + boolean setExplicitlyToDefault, + boolean mustCastForNull, + Type nullCastType) { super( rhs, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; - this.includeSourceNullCheck = includeSourceNullCheck( rhs, nvms, targetType ); + this.includeSourceNullCheck = includeSourceNullCheck; + this.setExplicitlyToDefault = setExplicitlyToDefault; + this.setExplicitlyToNull = setExplicitlyToNull; + this.mustCastForNull = mustCastForNull; + this.nullCastType = nullCastType; } public SetterWrapper(Assignment rhs, List thrownTypesToExclude, boolean fieldAssignment ) { super( rhs, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; this.includeSourceNullCheck = false; + this.setExplicitlyToNull = false; + this.setExplicitlyToDefault = false; + this.mustCastForNull = false; + this.nullCastType = null; } @Override public List getThrownTypes() { List parentThrownTypes = super.getThrownTypes(); - List result = new ArrayList( parentThrownTypes ); + List result = new ArrayList<>( parentThrownTypes ); for ( Type thrownTypeToExclude : thrownTypesToExclude ) { for ( Type parentThrownType : parentThrownTypes ) { if ( parentThrownType.isAssignableTo( thrownTypeToExclude ) ) { @@ -68,30 +69,28 @@ public List getThrownTypes() { return result; } + @Override + public Set getImportTypes() { + Set imported = new HashSet<>( super.getImportTypes() ); + if ( isSetExplicitlyToNull() && isMustCastForNull() ) { + imported.add( nullCastType ); + } + return imported; + } + + public boolean isSetExplicitlyToNull() { + return setExplicitlyToNull; + } + + public boolean isSetExplicitlyToDefault() { + return setExplicitlyToDefault; + } + public boolean isIncludeSourceNullCheck() { return includeSourceNullCheck; } - /** - * Wraps the assignment in a target setter. include a null check when - * - * - Not if source is the parameter iso property, because the null check is than handled by the bean mapping - * - Not when source is primitive, you can't null check a primitive - * - The source property is fed to a conversion somehow before its assigned to the target - * - The user decided to ALLWAYS include a null check - * - When there's a source local variable name defined (e.g. nested source properties) - * - TODO: The last one I forgot..? - * - * @param rhs the source righthand side - * @param nvms null value check strategy - * @param targetType the target type - * - * @return include a null check - */ - private boolean includeSourceNullCheck(Assignment rhs, NullValueCheckStrategyPrism nvms, Type targetType) { - return !rhs.isSourceReferenceParameter() - && !rhs.getSourceType().isPrimitive() - && (ALWAYS == nvms || rhs.getType().isConverted() || rhs.getSourceLocalVarName() != null - || (rhs.getType().isDirect() && targetType.isPrimitive())); + public boolean isMustCastForNull() { + return mustCastForNull; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.java index 98b298f567..9f84aeeff8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.java index dca19ec1c2..8ef71f7c0d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.java @@ -1,34 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; -import static org.mapstruct.ap.internal.model.common.Assignment.AssignmentType.DIRECT; - import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.NewInstanceCreation; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import static org.mapstruct.ap.internal.model.common.Assignment.AssignmentType.DIRECT; + /** * This wrapper handles the situation where an assignment is done via the setter and a null check is needed. * This is needed when a direct assignment is used, or if the user has chosen the appropriate strategy @@ -39,14 +27,13 @@ public class SetterWrapperForCollectionsAndMapsWithNullCheck extends WrapperForC private final Type targetType; private final TypeFactory typeFactory; - private final boolean mapNullToDefault; + private final NewInstanceCreation newInstance; public SetterWrapperForCollectionsAndMapsWithNullCheck(Assignment decoratedAssignment, List thrownTypesToExclude, Type targetType, TypeFactory typeFactory, - boolean fieldAssignment, - boolean mapNullToDefault) { + boolean fieldAssignment) { super( decoratedAssignment, thrownTypesToExclude, @@ -55,40 +42,34 @@ public SetterWrapperForCollectionsAndMapsWithNullCheck(Assignment decoratedAssig ); this.targetType = targetType; this.typeFactory = typeFactory; - this.mapNullToDefault = mapNullToDefault; + this.newInstance = NewInstanceCreation.forType( targetType ); } @Override public Set getImportTypes() { - Set imported = new HashSet( super.getImportTypes() ); + Set imported = new HashSet<>( super.getImportTypes() ); if ( isDirectAssignment() ) { - if ( targetType.getImplementationType() != null ) { - imported.addAll( targetType.getImplementationType().getImportTypes() ); - } - else { - imported.addAll( targetType.getImportTypes() ); - } - + imported.addAll( newInstance.getImportTypes() ); if ( isEnumSet() ) { imported.add( typeFactory.getType( EnumSet.class ) ); } } - if (isDirectAssignment() || getSourcePresenceCheckerReference() == null ) { + if ( isDirectAssignment() || getSourcePresenceCheckerReference() == null ) { imported.addAll( getNullCheckLocalVarType().getImportTypes() ); } return imported; } + public NewInstanceCreation getNewInstance() { + return newInstance; + } + public boolean isDirectAssignment() { return getType() == DIRECT; } public boolean isEnumSet() { - return "java.util.EnumSet".equals( targetType.getFullyQualifiedName() ); - } - - public boolean isMapNullToDefault() { - return mapNullToDefault; + return targetType.isEnumSet(); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/StreamAdderWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/StreamAdderWrapper.java new file mode 100644 index 0000000000..21a028c79f --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/StreamAdderWrapper.java @@ -0,0 +1,78 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.assignment; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + +import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Nouns; + +import static org.mapstruct.ap.internal.util.Collections.first; + +/** + * Wraps the assignment in a target setter. + * + * @author Sebastian Haberey + */ +public class StreamAdderWrapper extends AssignmentWrapper { + + private final List thrownTypesToExclude; + private final Type adderType; + + public StreamAdderWrapper(Assignment rhs, + List thrownTypesToExclude, + boolean fieldAssignment, + String targetPropertyName ) { + super( rhs, fieldAssignment ); + this.thrownTypesToExclude = thrownTypesToExclude; + String desiredName = Nouns.singularize( targetPropertyName ); + rhs.setSourceLocalVarName( rhs.createUniqueVarName( desiredName ) ); + adderType = first( getSourceType().determineTypeArguments( Stream.class ) ); + } + + @Override + public List getThrownTypes() { + List parentThrownTypes = super.getThrownTypes(); + List result = new ArrayList<>( parentThrownTypes ); + for ( Type thrownTypeToExclude : thrownTypesToExclude ) { + for ( Type parentExceptionType : parentThrownTypes ) { + if ( parentExceptionType.isAssignableTo( thrownTypeToExclude ) ) { + result.remove( parentExceptionType ); + } + } + } + return result; + } + + public Type getAdderType() { + return adderType; + } + + public boolean isIncludeSourceNullCheck() { + return true; + } + + public boolean isSetExplicitlyToNull() { + return false; + } + + public boolean isSetExplicitlyToDefault() { + return false; + } + + @Override + public Set getImportTypes() { + Set imported = new HashSet<>( super.getImportTypes() ); + imported.add( adderType.getTypeBound() ); + return imported; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java index 17f6bd4fc9..c80b5293c8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -24,6 +11,7 @@ import java.util.Set; import org.mapstruct.ap.internal.model.common.Assignment; +import org.mapstruct.ap.internal.model.common.NewInstanceCreation; import org.mapstruct.ap.internal.model.common.Type; /** @@ -35,9 +23,11 @@ public class UpdateWrapper extends AssignmentWrapper { private final List thrownTypesToExclude; private final Assignment factoryMethod; - private final Type targetImplementationType; + private final NewInstanceCreation newInstance; private final boolean includeSourceNullCheck; - private final boolean mapNullToDefault; + private final boolean setExplicitlyToNull; + private final boolean setExplicitlyToDefault; + private final boolean mustCastForNull; public UpdateWrapper( Assignment decoratedAssignment, List thrownTypesToExclude, @@ -45,33 +35,23 @@ public UpdateWrapper( Assignment decoratedAssignment, boolean fieldAssignment, Type targetType, boolean includeSourceNullCheck, - boolean mapNullToDefault ) { + boolean setExplicitlyToNull, + boolean setExplicitlyToDefault, + boolean mustCastForNull) { super( decoratedAssignment, fieldAssignment ); this.thrownTypesToExclude = thrownTypesToExclude; this.factoryMethod = factoryMethod; - this.targetImplementationType = determineImplType( factoryMethod, targetType ); + this.newInstance = ( factoryMethod == null ) ? NewInstanceCreation.forType( targetType ) : null; this.includeSourceNullCheck = includeSourceNullCheck; - this.mapNullToDefault = mapNullToDefault; - } - - private static Type determineImplType(Assignment factoryMethod, Type targetType) { - if ( factoryMethod != null ) { - //If we have factory method then we won't use the targetType - return null; - } - if ( targetType.getImplementationType() != null ) { - // it's probably a collection or something - return targetType.getImplementationType(); - } - - // no factory method means we create a new instance ourself and thus need to import the type - return targetType; + this.setExplicitlyToDefault = setExplicitlyToDefault; + this.setExplicitlyToNull = setExplicitlyToNull; + this.mustCastForNull = mustCastForNull; } @Override public List getThrownTypes() { List parentThrownTypes = super.getThrownTypes(); - List result = new ArrayList( parentThrownTypes ); + List result = new ArrayList<>( parentThrownTypes ); for ( Type thrownTypeToExclude : thrownTypesToExclude ) { for ( Type parentThrownType : parentThrownTypes ) { if ( parentThrownType.isAssignableTo( thrownTypeToExclude ) ) { @@ -84,14 +64,12 @@ public List getThrownTypes() { @Override public Set getImportTypes() { - Set imported = new HashSet(); - imported.addAll( super.getImportTypes() ); + Set imported = new HashSet<>( super.getImportTypes() ); if ( factoryMethod != null ) { imported.addAll( factoryMethod.getImportTypes() ); } - if ( targetImplementationType != null ) { - imported.add( targetImplementationType ); - imported.addAll( targetImplementationType.getTypeParameters() ); + if ( newInstance != null ) { + imported.addAll( newInstance.getImportTypes() ); } return imported; } @@ -100,11 +78,23 @@ public Assignment getFactoryMethod() { return factoryMethod; } + public NewInstanceCreation getNewInstance() { + return newInstance; + } + public boolean isIncludeSourceNullCheck() { return includeSourceNullCheck; } - public boolean isMapNullToDefault() { - return mapNullToDefault; + public boolean isSetExplicitlyToNull() { + return setExplicitlyToNull; + } + + public boolean isSetExplicitlyToDefault() { + return setExplicitlyToDefault; + } + + public boolean isMustCastForNull() { + return mustCastForNull; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/WrapperForCollectionsAndMaps.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/WrapperForCollectionsAndMaps.java index 44411a4448..e8b1f88457 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/WrapperForCollectionsAndMaps.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/WrapperForCollectionsAndMaps.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.assignment; @@ -50,13 +37,13 @@ public WrapperForCollectionsAndMaps(Assignment rhs, else { this.nullCheckLocalVarType = targetType; } - this.nullCheckLocalVarName = rhs.createLocalVarName( nullCheckLocalVarType.getName() ); + this.nullCheckLocalVarName = rhs.createUniqueVarName( nullCheckLocalVarType.getName() ); } @Override public List getThrownTypes() { List parentThrownTypes = super.getThrownTypes(); - List result = new ArrayList( parentThrownTypes ); + List result = new ArrayList<>( parentThrownTypes ); for ( Type thrownTypeToExclude : thrownTypesToExclude ) { for ( Type parentThrownType : parentThrownTypes ) { if ( parentThrownType.isAssignableTo( thrownTypeToExclude ) ) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/package-info.java index aff525bd1c..9a68f1f632 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/assignment/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** * Meta-model of assignments. There are currently three types of assignment: diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/AbstractReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/AbstractReference.java new file mode 100644 index 0000000000..72f2b8c8fe --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/AbstractReference.java @@ -0,0 +1,128 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.beanmapping; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.util.Strings; + +import static org.mapstruct.ap.internal.util.Collections.first; +import static org.mapstruct.ap.internal.util.Collections.last; + +/** + * Class acts as a common base class for {@link TargetReference} and {@link SourceReference}. + * + * @author sjaak + */ +public abstract class AbstractReference { + + private final Parameter parameter; + private final List propertyEntries; + private final boolean isValid; + + protected AbstractReference(Parameter sourceParameter, List sourcePropertyEntries, boolean isValid) { + this.parameter = sourceParameter; + this.propertyEntries = sourcePropertyEntries; + this.isValid = isValid; + } + + public Parameter getParameter() { + return parameter; + } + + public List getPropertyEntries() { + return propertyEntries; + } + + public boolean isValid() { + return isValid; + } + + public List getElementNames() { + List elementNames = new ArrayList<>(); + if ( parameter != null ) { + // only relevant for source properties + elementNames.add( parameter.getName() ); + } + for ( PropertyEntry propertyEntry : propertyEntries ) { + elementNames.add( propertyEntry.getName() ); + } + return elementNames; + } + + /** + * @return the property name on the shallowest nesting level + */ + public PropertyEntry getShallowestProperty() { + if ( propertyEntries.isEmpty() ) { + return null; + } + return first( propertyEntries ); + } + + /** + * @return the property name on the shallowest nesting level + */ + public String getShallowestPropertyName() { + if ( propertyEntries.isEmpty() ) { + return null; + } + return first( propertyEntries ).getName(); + } + + /** + * @return the property name on the deepest nesting level + */ + public PropertyEntry getDeepestProperty() { + if ( propertyEntries.isEmpty() ) { + return null; + } + return last( propertyEntries ); + } + + /** + * @return the property name on the deepest nesting level + */ + public String getDeepestPropertyName() { + if ( propertyEntries.isEmpty() ) { + return null; + } + return last( propertyEntries ).getName(); + } + + public boolean isNested() { + return propertyEntries.size() > 1; + } + + @Override + public String toString() { + + String result = ""; + if ( !isValid ) { + result = "invalid"; + } + else if ( propertyEntries.isEmpty() ) { + if ( parameter != null ) { + result = String.format( "parameter \"%s %s\"", parameter.getType().describe(), parameter.getName() ); + } + } + else if ( propertyEntries.size() == 1 ) { + PropertyEntry propertyEntry = propertyEntries.get( 0 ); + result = String.format( "property \"%s %s\"", propertyEntry.getType().describe(), propertyEntry.getName() ); + } + else { + PropertyEntry lastPropertyEntry = propertyEntries.get( propertyEntries.size() - 1 ); + result = String.format( + "property \"%s %s\"", + lastPropertyEntry.getType().describe(), + Strings.join( getElementNames(), "." ) + ); + } + return result; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/MappingReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/MappingReference.java new file mode 100644 index 0000000000..9baa84dc77 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/MappingReference.java @@ -0,0 +1,128 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.beanmapping; + +import java.util.Objects; + +import org.mapstruct.ap.internal.model.source.MappingOptions; + +/** + * Represents the intermediate (nesting) state of the {@link MappingOptions} in this class. + */ +public class MappingReference { + + private MappingOptions mapping; + + private TargetReference targetReference; + + private SourceReference sourceReference; + + public MappingReference(MappingOptions mapping, TargetReference targetReference, SourceReference sourceReference) { + this.mapping = mapping; + this.targetReference = targetReference; + this.sourceReference = sourceReference; + } + + public MappingOptions getMapping() { + return mapping; + } + + public SourceReference getSourceReference() { + return sourceReference; + } + + public void setSourceReference(SourceReference sourceReference) { + this.sourceReference = sourceReference; + } + + public TargetReference getTargetReference() { + return targetReference; + } + + public MappingReference popTargetReference() { + if ( targetReference != null ) { + TargetReference newTargetReference = targetReference.pop(); + if ( newTargetReference != null ) { + return new MappingReference(mapping, newTargetReference, sourceReference ); + } + } + return null; + } + + public MappingReference popSourceReference() { + if ( sourceReference != null ) { + SourceReference newSourceReference = sourceReference.pop(); + if ( newSourceReference != null ) { + return new MappingReference(mapping, targetReference, newSourceReference ); + } + } + return null; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + MappingReference that = (MappingReference) o; + if ( ".".equals( that.mapping.getTargetName() ) ) { + // target this will never be equal to any other target this or any other. + return false; + } + + if ( !Objects.equals( mapping.getTargetName(), that.mapping.getTargetName() ) ) { + return false; + } + + if ( !Objects.equals( mapping.getConstant(), that.mapping.getConstant() ) ) { + return false; + } + + if ( !Objects.equals( mapping.getJavaExpression(), that.mapping.getJavaExpression() ) ) { + return false; + } + + if ( sourceReference == null ) { + return that.sourceReference == null; + } + + if ( that.sourceReference == null ) { + return false; + } + + + if ( !Objects.equals( sourceReference.getPropertyEntries(), that.sourceReference.getPropertyEntries() ) ) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return Objects.hash( mapping ); + } + + public boolean isValid( ) { + return sourceReference == null || sourceReference.isValid(); + } + + @Override + public String toString() { + String targetRefStr = targetReference.toString(); + String sourceRefStr = "null"; + if ( sourceReference != null ) { + sourceRefStr = sourceReference.toString(); + } + return "MappingReference {" + + "\n sourceReference='" + sourceRefStr + "\'," + + "\n targetReference='" + targetRefStr + "\'," + + "\n}"; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/MappingReferences.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/MappingReferences.java new file mode 100644 index 0000000000..edc5b3157e --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/MappingReferences.java @@ -0,0 +1,163 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.beanmapping; + +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.model.source.MappingOptions; +import org.mapstruct.ap.internal.model.source.SourceMethod; +import org.mapstruct.ap.internal.util.FormattingMessager; + +public class MappingReferences { + + private static final MappingReferences EMPTY = new MappingReferences( Collections.emptySet(), false ); + + private final Set mappingReferences; + private final boolean restrictToDefinedMappings; + private final boolean forForgedMethods; + + public static MappingReferences empty() { + return EMPTY; + } + + public static MappingReferences forSourceMethod(SourceMethod sourceMethod, + Type targetType, + Set targetProperties, + FormattingMessager messager, + TypeFactory typeFactory) { + + Set references = new LinkedHashSet<>(); + + for ( MappingOptions mapping : sourceMethod.getOptions().getMappings() ) { + + // handle source reference + SourceReference sourceReference = new SourceReference.BuilderFromMapping().mapping( mapping ) + .method( sourceMethod ) + .messager( messager ) + .typeFactory( typeFactory ) + .build(); + + // handle target reference + TargetReference targetReference = new TargetReference.Builder().mapping( mapping ) + .method( sourceMethod ) + .messager( messager ) + .typeFactory( typeFactory ) + .targetProperties( targetProperties ) + .targetType( targetType ) + .build(); + + // add when inverse is also valid + MappingReference mappingReference = new MappingReference( mapping, targetReference, sourceReference ); + if ( isValidWhenInversed( mappingReference ) ) { + references.add( mappingReference ); + } + } + return new MappingReferences( references, false ); + } + + public MappingReferences(Set mappingReferences, boolean restrictToDefinedMappings) { + this.mappingReferences = mappingReferences; + this.restrictToDefinedMappings = restrictToDefinedMappings; + this.forForgedMethods = restrictToDefinedMappings; + } + + public MappingReferences(Set mappingReferences, boolean restrictToDefinedMappings, + boolean forForgedMethods) { + this.mappingReferences = mappingReferences; + this.restrictToDefinedMappings = restrictToDefinedMappings; + this.forForgedMethods = forForgedMethods; + } + + public Set getMappingReferences() { + return mappingReferences; + } + + public boolean isRestrictToDefinedMappings() { + return restrictToDefinedMappings; + } + + public boolean isForForgedMethods() { + return forForgedMethods; + } + + /** + * @return all dependencies to other properties the contained mappings are dependent on + */ + public Set collectNestedDependsOn() { + + Set nestedDependsOn = new LinkedHashSet<>(); + for ( MappingReference mapping : getMappingReferences() ) { + nestedDependsOn.addAll( mapping.getMapping().getDependsOn() ); + } + return nestedDependsOn; + } + + /** + * Check there are nested target references for this mapping options. + * + * @return boolean, true if there are nested target references + */ + public boolean hasNestedTargetReferences() { + + for ( MappingReference mappingRef : mappingReferences ) { + TargetReference targetReference = mappingRef.getTargetReference(); + if ( targetReference.isNested() ) { + return true; + } + + } + return false; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( !( o instanceof MappingReferences ) ) { + return false; + } + + MappingReferences that = (MappingReferences) o; + + if ( restrictToDefinedMappings != that.restrictToDefinedMappings ) { + return false; + } + if ( forForgedMethods != that.forForgedMethods ) { + return false; + } + if ( !Objects.equals( mappingReferences, that.mappingReferences ) ) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + return mappingReferences != null ? mappingReferences.hashCode() : 0; + } + + /** + * MapStruct filters automatically inversed invalid methods out. TODO: this is a principle we should discuss! + * @param mappingRef + * @return + */ + private static boolean isValidWhenInversed(MappingReference mappingRef) { + MappingOptions mapping = mappingRef.getMapping(); + if ( mapping.getInheritContext() != null && mapping.getInheritContext().isReversed() ) { + return ( mappingRef.getSourceReference() == null || + mappingRef.getSourceReference().isValid() ); + } + return true; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/PropertyEntry.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/PropertyEntry.java new file mode 100644 index 0000000000..a3c8a74e3f --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/PropertyEntry.java @@ -0,0 +1,101 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.beanmapping; + +import java.util.Arrays; + +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; + +/** + * A PropertyEntry contains information on the name, readAccessor and presenceCheck (for source) + * and return type of property. + */ +public class PropertyEntry { + + private final String[] fullName; + private final ReadAccessor readAccessor; + private final PresenceCheckAccessor presenceChecker; + private final Type type; + + /** + * Constructor used to create {@link TargetReference} property entries from a mapping + * + * @param fullName + * @param readAccessor + * @param type + */ + private PropertyEntry(String[] fullName, ReadAccessor readAccessor, PresenceCheckAccessor presenceChecker, + Type type) { + this.fullName = fullName; + this.readAccessor = readAccessor; + this.presenceChecker = presenceChecker; + this.type = type; + } + + /** + * Constructor used to create {@link SourceReference} property entries from a mapping + * + * @param name name of the property (dot separated) + * @param readAccessor its read accessor + * @param presenceChecker its presence Checker + * @param type type of the property + * @return the property entry for given parameters. + */ + public static PropertyEntry forSourceReference(String[] name, ReadAccessor readAccessor, + PresenceCheckAccessor presenceChecker, Type type) { + return new PropertyEntry( name, readAccessor, presenceChecker, type ); + } + + public String getName() { + return fullName[fullName.length - 1]; + } + + public ReadAccessor getReadAccessor() { + return readAccessor; + } + + public PresenceCheckAccessor getPresenceChecker() { + return presenceChecker; + } + + public Type getType() { + return type; + } + + public String getFullName() { + return Strings.join( Arrays.asList( fullName ), "." ); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 23 * hash + Arrays.deepHashCode( this.fullName ); + return hash; + } + + @Override + public boolean equals(Object obj) { + if ( this == obj ) { + return true; + } + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + final PropertyEntry other = (PropertyEntry) obj; + return Arrays.deepEquals( this.fullName, other.fullName ); + } + + @Override + public String toString() { + return type + " " + Strings.join( Arrays.asList( fullName ), "." ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/SourceReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/SourceReference.java new file mode 100644 index 0000000000..c37b12e311 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/SourceReference.java @@ -0,0 +1,478 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.beanmapping; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.type.DeclaredType; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.model.source.MappingOptions; +import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; + +import static org.mapstruct.ap.internal.model.beanmapping.PropertyEntry.forSourceReference; +import static org.mapstruct.ap.internal.util.Collections.last; + +/** + * This class describes the source side of a property mapping. + *

    + * It contains the source parameter, and all individual (nested) property entries. So consider the following + * mapping method: + * + *

    + * @Mapping(target = "propC", source = "in.propA.propB")
    + * TypeB mappingMethod(TypeA in);
    + * 
    + * + * Then: + *
      + *
    • {@code parameter} will describe {@code in}
    • + *
    • {@code propertyEntries[0]} will describe {@code propA}
    • + *
    • {@code propertyEntries[1]} will describe {@code propB}
    • + *
    + * + * After building, {@link #isValid()} will return true when no problems are detected during building. + * + * @author Sjaak Derksen + * @author Filip Hrisafov + */ +public class SourceReference extends AbstractReference { + + /** + * Builds a {@link SourceReference} from an {@code @Mappping}. + */ + public static class BuilderFromMapping { + + private Method method; + private FormattingMessager messager = null; + private TypeFactory typeFactory; + + private boolean isForwarded = false; + private Method templateMethod = null; + private String sourceName; + private AnnotationMirror annotationMirror; + private AnnotationValue sourceAnnotationValue; + + public BuilderFromMapping messager(FormattingMessager messager) { + this.messager = messager; + return this; + } + + public BuilderFromMapping mapping(MappingOptions mapping) { + this.sourceName = mapping.getSourceName(); + this.annotationMirror = mapping.getMirror(); + this.sourceAnnotationValue = mapping.getSourceAnnotationValue(); + if ( mapping.getInheritContext() != null ) { + isForwarded = mapping.getInheritContext().isForwarded(); + templateMethod = mapping.getInheritContext().getTemplateMethod(); + } + return this; + } + + public BuilderFromMapping method(Method method) { + this.method = method; + return this; + } + + public BuilderFromMapping typeFactory(TypeFactory typeFactory) { + this.typeFactory = typeFactory; + return this; + } + + public BuilderFromMapping sourceName(String sourceName) { + this.sourceName = sourceName; + return this; + } + + public SourceReference build() { + + if ( sourceName == null ) { + return null; + } + + Objects.requireNonNull( messager ); + + String sourceNameTrimmed = sourceName.trim(); + if ( !sourceName.equals( sourceNameTrimmed ) ) { + messager.printMessage( + method.getExecutable(), + annotationMirror, + sourceAnnotationValue, + Message.PROPERTYMAPPING_WHITESPACE_TRIMMED, + sourceName, + sourceNameTrimmed + ); + } + + String[] segments = sourceNameTrimmed.split( "\\." ); + + // start with an invalid source reference + SourceReference result = new SourceReference( null, new ArrayList<>( ), false ); + if ( method.getSourceParameters().size() > 1 ) { + Parameter parameter = fetchMatchingParameterFromFirstSegment( segments ); + if ( parameter != null ) { + result = buildFromMultipleSourceParameters( segments, parameter ); + } + } + else { + Parameter parameter = method.getSourceParameters().get( 0 ); + result = buildFromSingleSourceParameters( segments, parameter ); + } + return result; + + } + + /** + * When there is only one source parameters, the first segment name of the property may, or may not match + * the parameter name to avoid ambiguity + * + * consider: {@code Target map( Source1 source1 )} + * entries in a @Mapping#source can be "source1.propx" or just "propx" to be valid + * + * @param segments the segments of @Mapping#source + * @param parameter the one and only parameter + * @return the source reference + */ + private SourceReference buildFromSingleSourceParameters(String[] segments, Parameter parameter) { + boolean foundEntryMatch; + + boolean allowedMapToBean = false; + if ( segments.length > 0 ) { + if ( parameter.getType().isMapType() ) { + // When the parameter type is a map and the parameter name matches the first segment + // then the first segment should not be treated as a property of the map + allowedMapToBean = !segments[0].equals( parameter.getName() ); + } + } + String[] propertyNames = segments; + List entries = matchWithSourceAccessorTypes( + parameter.getType(), + propertyNames, + allowedMapToBean + ); + foundEntryMatch = ( entries.size() == propertyNames.length ); + + if ( !foundEntryMatch ) { + //Lets see if the expression contains the parameterName, so parameterName.propName1.propName2 + if ( getSourceParameterFromMethodOrTemplate( segments[0] ) != null ) { + propertyNames = Arrays.copyOfRange( segments, 1, segments.length ); + entries = matchWithSourceAccessorTypes( parameter.getType(), propertyNames, true ); + foundEntryMatch = ( entries.size() == propertyNames.length ); + } + else { + // segment[0] cannot be attributed to the parameter name. + parameter = null; + } + } + + if ( !foundEntryMatch ) { + reportErrorOnNoMatch( parameter, propertyNames, entries ); + } + + return new SourceReference( parameter, entries, foundEntryMatch ); + } + + /** + * When there are more than one source parameters, the first segment name of the property + * needs to match the parameter name to avoid ambiguity + * + * @param segments the segments of @Mapping#source + * @param parameter the relevant source parameter + * @return the source reference + */ + private SourceReference buildFromMultipleSourceParameters(String[] segments, Parameter parameter) { + + boolean foundEntryMatch; + + String[] propertyNames = new String[0]; + List entries = new ArrayList<>(); + + if ( segments.length > 1 && parameter != null ) { + propertyNames = Arrays.copyOfRange( segments, 1, segments.length ); + entries = matchWithSourceAccessorTypes( parameter.getType(), propertyNames, true ); + foundEntryMatch = ( entries.size() == propertyNames.length ); + } + else { + // its only a parameter, no property + foundEntryMatch = true; + } + + if ( !foundEntryMatch ) { + reportErrorOnNoMatch( parameter, propertyNames, entries ); + } + + return new SourceReference( parameter, entries, foundEntryMatch ); + } + + /** + * When there are more than one source parameters, the first segment name of the property + * needs to match the parameter name to avoid ambiguity + * + * consider: {@code Target map( Source1 source1, Source2 source2 )} + * entries in a @Mapping#source need to be "source1.propx" or "source2.propy.propz" to be valid + * + * @param segments the segments of @Mapping#source + * @return parameter that matches with first segment of @Mapping#source + */ + private Parameter fetchMatchingParameterFromFirstSegment(String[] segments ) { + Parameter parameter = null; + if ( segments.length > 0 ) { + String parameterName = segments[0]; + parameter = getSourceParameterFromMethodOrTemplate( parameterName ); + if ( parameter == null ) { + reportMappingError( + Message.PROPERTYMAPPING_INVALID_PARAMETER_NAME, + parameterName, + Strings.join( method.getSourceParameters(), ", ", Parameter::getName ) + ); + } + } + return parameter; + } + + private Parameter getSourceParameterFromMethodOrTemplate(String parameterName ) { + + Parameter result = null; + if ( isForwarded ) { + Parameter parameter = Parameter.getSourceParameter( templateMethod.getParameters(), parameterName ); + if ( parameter != null ) { + + // When forward inheriting we should find the matching source parameter by type + // If there are multiple parameters of the same type + // then we fallback to match the parameter name to the current method source parameters + for ( Parameter sourceParameter : method.getSourceParameters() ) { + if ( sourceParameter.getType().isAssignableTo( parameter.getType() ) ) { + if ( result == null ) { + result = sourceParameter; + } + else { + // When we reach here it means that we found a second source parameter + // that has the same type, then fallback to the matching source parameter + // in the current method + result = Parameter.getSourceParameter( method.getParameters(), parameterName ); + break; + } + } + } + } + } + else { + result = Parameter.getSourceParameter( method.getParameters(), parameterName ); + } + return result; + } + + private void reportErrorOnNoMatch( Parameter parameter, String[] propertyNames, List entries) { + if ( parameter != null ) { + reportMappingError( Message.PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER, parameter.getName(), + Strings.join( Arrays.asList( propertyNames ), "." ) + ); + } + else { + int notFoundPropertyIndex = 0; + Type sourceType = method.getParameters().get( 0 ).getType(); + if ( !entries.isEmpty() ) { + notFoundPropertyIndex = entries.size(); + sourceType = last( entries ).getType(); + } + + Set readProperties = sourceType.getPropertyReadAccessors().keySet(); + + if ( !readProperties.isEmpty() ) { + String mostSimilarWord = Strings.getMostSimilarWord( + propertyNames[notFoundPropertyIndex], + readProperties + ); + + List elements = new ArrayList<>( + Arrays.asList( propertyNames ).subList( 0, notFoundPropertyIndex ) + ); + elements.add( mostSimilarWord ); + reportMappingError( + Message.PROPERTYMAPPING_INVALID_PROPERTY_NAME, sourceName, Strings.join( elements, "." ) + ); + } + else { + reportMappingError( + Message.PROPERTYMAPPING_INVALID_PROPERTY_NAME_SOURCE_HAS_NO_PROPERTIES, + sourceName, + sourceType.describe() + ); + } + } + } + + private List matchWithSourceAccessorTypes(Type type, String[] entryNames, + boolean allowedMapToBean) { + List sourceEntries = new ArrayList<>(); + Type newType = type; + for ( int i = 0; i < entryNames.length; i++ ) { + boolean matchFound = false; + Type noBoundsType = newType.withoutBounds(); + if ( noBoundsType.isOptionalType() ) { + noBoundsType = noBoundsType.getOptionalBaseType(); + } + ReadAccessor readAccessor = noBoundsType.getReadAccessor( entryNames[i], i > 0 || allowedMapToBean ); + if ( readAccessor != null ) { + PresenceCheckAccessor presenceChecker = noBoundsType.getPresenceChecker( entryNames[i] ); + newType = typeFactory.getReturnType( + (DeclaredType) noBoundsType.getTypeMirror(), + readAccessor + ); + sourceEntries.add( forSourceReference( + Arrays.copyOf( entryNames, i + 1 ), + readAccessor, + presenceChecker, + newType + ) ); + matchFound = true; + } + if ( !matchFound ) { + break; + } + } + return sourceEntries; + } + + private void reportMappingError(Message msg, Object... objects) { + messager.printMessage( method.getExecutable(), annotationMirror, sourceAnnotationValue, msg, objects ); + } + } + + /** + * Builds a {@link SourceReference} from a property. + */ + public static class BuilderFromProperty { + + private String name; + private ReadAccessor readAccessor; + private PresenceCheckAccessor presenceChecker; + private Type type; + private Parameter sourceParameter; + + public BuilderFromProperty name(String name) { + this.name = name; + return this; + } + + public BuilderFromProperty readAccessor(ReadAccessor readAccessor) { + this.readAccessor = readAccessor; + return this; + } + + public BuilderFromProperty presenceChecker(PresenceCheckAccessor presenceChecker) { + this.presenceChecker = presenceChecker; + return this; + } + + public BuilderFromProperty type(Type type) { + this.type = type; + return this; + } + + public BuilderFromProperty sourceParameter(Parameter sourceParameter) { + this.sourceParameter = sourceParameter; + return this; + } + + public SourceReference build() { + List sourcePropertyEntries = new ArrayList<>(); + if ( readAccessor != null ) { + sourcePropertyEntries.add( forSourceReference( + new String[] { name }, + readAccessor, + presenceChecker, + type + ) ); + } + return new SourceReference( sourceParameter, sourcePropertyEntries, true ); + } + } + + /** + * Builds a {@link SourceReference} from a property. + */ + public static class BuilderFromSourceReference { + + private Parameter sourceParameter; + private SourceReference sourceReference; + + public BuilderFromSourceReference sourceReference(SourceReference sourceReference) { + this.sourceReference = sourceReference; + return this; + } + + public BuilderFromSourceReference sourceParameter(Parameter sourceParameter) { + this.sourceParameter = sourceParameter; + return this; + } + + public SourceReference build() { + return new SourceReference( sourceParameter, sourceReference.getPropertyEntries(), true ); + } + } + + private SourceReference(Parameter sourceParameter, List sourcePropertyEntries, boolean isValid) { + super( sourceParameter, sourcePropertyEntries, isValid ); + } + + public SourceReference pop() { + if ( getPropertyEntries().size() > 1 ) { + List newPropertyEntries = + new ArrayList<>( getPropertyEntries().subList( 1, getPropertyEntries().size() ) ); + return new SourceReference( getParameter(), newPropertyEntries, isValid() ); + } + else { + return null; + } + } + + public List push(TypeFactory typeFactory, FormattingMessager messager, Method method ) { + List result = new ArrayList<>(); + PropertyEntry deepestProperty = getDeepestProperty(); + if ( deepestProperty != null ) { + Type type = deepestProperty.getType(); + Map newDeepestReadAccessors = type.getPropertyReadAccessors(); + String parameterName = getParameter().getName(); + String deepestPropertyFullName = deepestProperty.getFullName(); + for ( Map.Entry newDeepestReadAccessorEntry : newDeepestReadAccessors.entrySet() ) { + // Always include the parameter name in the new full name. + // Otherwise multi source parameters might be reported incorrectly + String newFullName = + parameterName + "." + deepestPropertyFullName + "." + newDeepestReadAccessorEntry.getKey(); + SourceReference sourceReference = new BuilderFromMapping() + .sourceName( newFullName ) + .method( method ) + .messager( messager ) + .typeFactory( typeFactory ) + .build(); + result.add( sourceReference ); + } + } + return result; + } + + public SourceReference withParameter(Parameter parameter) { + if ( parameter == null || getParameter() == parameter ) { + return this; + } + return new SourceReference( parameter, getPropertyEntries(), isValid() ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/TargetReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/TargetReference.java new file mode 100644 index 0000000000..961e519561 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/TargetReference.java @@ -0,0 +1,282 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.beanmapping; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.model.source.MappingOptions; +import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.Strings; + +import static org.mapstruct.ap.internal.util.Collections.first; + +/** + * This class describes the target side of a property mapping. + *

    + * It contains the target parameter, and all individual (nested) property entries. So consider the following mapping + * method: + * + *

    + * @Mapping(target = "propC", source = "in.propA.propB")
    + * TypeB mappingMethod(TypeA in);
    + * 
    + * + * Then: + *
      + *
    • {@code parameter} will describe {@code in}
    • + *
    • {@code propertyEntries[0]} will describe {@code propA}
    • + *
    • {@code propertyEntries[1]} will describe {@code propB}
    • + *
    + * + * @author Sjaak Derksen + */ +public class TargetReference { + + private final List pathProperties; + private final Parameter parameter; + private final List propertyEntries; + + public TargetReference(Parameter parameter, List propertyEntries) { + this( parameter, propertyEntries, Collections.emptyList() ); + } + + public TargetReference(Parameter parameter, List propertyEntries, List pathProperties) { + this.pathProperties = pathProperties; + this.parameter = parameter; + this.propertyEntries = propertyEntries; + } + + public List getPathProperties() { + return pathProperties; + } + + public List getPropertyEntries() { + return propertyEntries; + } + + public List getElementNames() { + List elementNames = new ArrayList<>(); + if ( parameter != null ) { + // only relevant for source properties + elementNames.add( parameter.getName() ); + } + elementNames.addAll( propertyEntries ); + return elementNames; + } + + /** + * @return the property name on the shallowest nesting level + */ + public String getShallowestPropertyName() { + if ( propertyEntries.isEmpty() ) { + return null; + } + return first( propertyEntries ); + } + + public boolean isNested() { + return propertyEntries.size() > 1; + } + + @Override + public String toString() { + + String result = ""; + if ( propertyEntries.isEmpty() ) { + if ( parameter != null ) { + result = String.format( "parameter \"%s %s\"", parameter.getType(), parameter.getName() ); + } + } + else if ( propertyEntries.size() == 1 ) { + String propertyEntry = propertyEntries.get( 0 ); + result = String.format( "property \"%s\"", propertyEntry ); + } + else { + result = String.format( + "property \"%s\"", + Strings.join( getElementNames(), "." ) + ); + } + return result; + } + + /** + * Builds a {@link TargetReference} from an {@code @Mappping}. + */ + public static class Builder { + + private Method method; + private FormattingMessager messager; + private TypeFactory typeFactory; + private Set targetProperties; + private Type targetType; + + // mapping parameters + private String targetName = null; + private MappingOptions mapping; + private AnnotationMirror annotationMirror = null; + private AnnotationValue targetAnnotationValue = null; + private AnnotationValue sourceAnnotationValue = null; + + public Builder messager(FormattingMessager messager) { + this.messager = messager; + return this; + } + + public Builder mapping(MappingOptions mapping) { + this.mapping = mapping; + this.targetName = mapping.getTargetName(); + this.annotationMirror = mapping.getMirror(); + this.targetAnnotationValue = mapping.getTargetAnnotationValue(); + this.sourceAnnotationValue = mapping.getSourceAnnotationValue(); + return this; + } + + public Builder typeFactory(TypeFactory typeFactory) { + this.typeFactory = typeFactory; + return this; + } + + public Builder method(Method method) { + this.method = method; + return this; + } + + public Builder targetProperties(Set targetProperties) { + this.targetProperties = targetProperties; + return this; + } + + public Builder targetType(Type targetType) { + this.targetType = targetType; + return this; + } + + public TargetReference build() { + + Objects.requireNonNull( method ); + Objects.requireNonNull( typeFactory ); + Objects.requireNonNull( messager ); + Objects.requireNonNull( targetType ); + + if ( targetName == null ) { + return null; + } + + String targetNameTrimmed = targetName.trim(); + if ( !targetName.equals( targetNameTrimmed ) ) { + messager.printMessage( + method.getExecutable(), + annotationMirror, + targetAnnotationValue, + Message.PROPERTYMAPPING_WHITESPACE_TRIMMED, + targetName, + targetNameTrimmed + ); + } + String[] segments = targetNameTrimmed.split( "\\." ); + Parameter parameter = method.getMappingTargetParameter(); + + // there can be 4 situations + // 1. Return type + // 2. An inverse target reference where the source parameter name is used in the original mapping + // 3. @MappingTarget, with + // 4. or without parameter name. + String[] targetPropertyNames = segments; + if ( segments.length > 1 ) { + String firstTargetProperty = targetPropertyNames[0]; + // If the first target property is not within the defined target properties, then check if it matches + // the source or target parameter + if ( !targetProperties.contains( firstTargetProperty ) ) { + if ( matchesSourceOrTargetParameter( firstTargetProperty, parameter ) ) { + targetPropertyNames = Arrays.copyOfRange( segments, 1, segments.length ); + } + } + } + + + List entries = new ArrayList<>( Arrays.asList( targetPropertyNames ) ); + + return new TargetReference( parameter, entries ); + } + + /** + * Validates that the {@code segment} is the same as the {@code targetParameter} or the {@code + * inverseSourceParameter} names + * + * @param segment that needs to be checked + * @param targetParameter the target parameter if it exists + * + * @return {@code true} if the segment matches the name of the {@code targetParameter} or the name of the + * {@code inverseSourceParameter} when this is a inverse {@link TargetReference} is being built, {@code + * false} otherwise + */ + private boolean matchesSourceOrTargetParameter(String segment, Parameter targetParameter) { + boolean matchesTargetParameter = targetParameter != null && targetParameter.getName().equals( segment ); + return matchesTargetParameter || matchesSourceOnInverseSourceParameter( segment ); + } + + /** + * Needed when we are building from inverse mapping. It is needed, so we can remove the first level if it is + * needed. + * E.g. If we have a mapping like: + * + * {@literal @}Mapping( target = "letterSignature", source = "dto.signature" ) + * + * When it is inversed it will look like: + * + * {@literal @}Mapping( target = "dto.signature", source = "letterSignature" ) + * + * The {@code dto} needs to be considered as a possibility for a target name only if a Target Reference for + * a inverse is created. + * + * @param segment that needs to be checked* + * + * @return on match when inverse and segment matches the one and only source parameter + */ + private boolean matchesSourceOnInverseSourceParameter(String segment) { + + boolean result = false; + MappingOptions.InheritContext inheritContext = mapping.getInheritContext(); + if ( inheritContext != null && inheritContext.isReversed() ) { + + Method templateMethod = inheritContext.getTemplateMethod(); + // there is only source parameter by definition when applying @InheritInverseConfiguration + Parameter inverseSourceParameter = first( templateMethod.getSourceParameters() ); + result = inverseSourceParameter.getName().equals( segment ); + } + return result; + } + } + + public TargetReference pop() { + if ( getPropertyEntries().size() > 1 ) { + List newPathProperties = new ArrayList<>( this.pathProperties ); + newPathProperties.add( getPropertyEntries().get( 0 ) ); + return new TargetReference( + null, + getPropertyEntries().subList( 1, getPropertyEntries().size() ), + newPathProperties + ); + } + else { + return null; + } + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/package-info.java new file mode 100644 index 0000000000..e616342c6f --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/beanmapping/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +/** + *

    + * helper classes used in {@link org.mapstruct.ap.internal.model.BeanMappingMethod} + *

    + */package org.mapstruct.ap.internal.model.beanmapping; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Accessibility.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Accessibility.java index 959c41212c..1988e4f90b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Accessibility.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Accessibility.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; import java.util.Set; - import javax.lang.model.element.Modifier; /** @@ -28,7 +14,7 @@ * @author Andreas Gudian */ public enum Accessibility { - PRIVATE( "private" ), DEFAULT( "" ), PROTECTED( "protected" ), PUBLIC( "public" ); + PRIVATE( "private" ), PACKAGE_PRIVATE( "" ), PROTECTED( "protected" ), PUBLIC( "public" ); private final String keyword; @@ -51,6 +37,6 @@ else if ( modifiers.contains( Modifier.PRIVATE ) ) { return PRIVATE; } - return DEFAULT; + return PACKAGE_PRIVATE; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Assignment.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Assignment.java index a25fab69c4..7ed0140d81 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Assignment.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Assignment.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -72,7 +59,7 @@ public boolean isConverted() { * * @return exceptions thrown */ - List getThrownTypes(); + List getThrownTypes(); /** * An assignment in itself can wrap another assignment. E.g.: @@ -103,7 +90,7 @@ public boolean isConverted() { * * @return source reference */ - String getSourcePresenceCheckerReference(); + PresenceCheck getSourcePresenceCheckerReference(); /** * the source type used in the matching process @@ -119,7 +106,7 @@ public boolean isConverted() { * * @return the desired name, made unique in the scope of the bean mapping. */ - String createLocalVarName( String desiredName ); + String createUniqueVarName(String desiredName ); /** * See {@link #setSourceLocalVarName(java.lang.String) } @@ -144,6 +131,22 @@ public boolean isConverted() { */ void setSourceLocalVarName(String sourceLocalVarName); + /** + * See {@link #getSourceLoopVarName()} (java.lang.String) } + * + * @return loop variable (can be null if not set) + */ + String getSourceLoopVarName(); + + /** + * Replaces the sourceLocalVar or sourceReference at the call site in the assignment in the template with this + * sourceLoopVarName. + * The sourceLocalVar can subsequently be used for e.g. null checking. + * + * @param sourceLoopVarName loop variable + */ + void setSourceLoopVarName(String sourceLoopVarName); + /** * Returns whether the type of assignment * diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/BuilderType.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/BuilderType.java index 1cfba42f2c..2b9c6d626b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/BuilderType.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/BuilderType.java @@ -1,31 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; import java.util.Collection; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.spi.BuilderInfo; /** + * Represents the information about a builder. + * How it can be constructed, the type it is building etc. + * * @author Filip Hrisafov */ public class BuilderType { @@ -95,15 +86,8 @@ public Collection getBuildMethods() { return buildMethods; } - public BuilderInfo asBuilderInfo() { - return new BuilderInfo.Builder() - .builderCreationMethod( this.builderCreationMethod ) - .buildMethod( this.buildMethods ) - .build(); - } - public static BuilderType create(BuilderInfo builderInfo, Type typeToBuild, TypeFactory typeFactory, - Types typeUtils) { + TypeUtils typeUtils) { if ( builderInfo == null ) { return null; } @@ -122,6 +106,11 @@ else if ( typeUtils.isSameType( builder.getTypeMirror(), builderCreationOwner ) owner = typeFactory.getType( builderCreationOwner ); } + // When the builderCreationMethod is constructor, its return type is Void. In this case the + // builder type should be the owner type. + if ( builderInfo.getBuilderCreationMethod().getKind() == ElementKind.CONSTRUCTOR ) { + builder = owner; + } return new BuilderType( builder, diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConstructorFragment.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConstructorFragment.java new file mode 100644 index 0000000000..89d2928999 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConstructorFragment.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.common; + +/** + * ConstructorFragments are 'code snippets' added to the constructor to initialize fields used by + * BuiltInMethod/HelperMethod + */ +public interface ConstructorFragment { +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConversionContext.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConversionContext.java index 17cfe9c7db..d3a29e30a4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConversionContext.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ConversionContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -34,6 +21,13 @@ public interface ConversionContext { */ Type getTargetType(); + /** + * Returns the source type of this conversion. + * + * @return The source type of this conversion. + */ + Type getSourceType(); + /** * Returns the date format if this conversion or built-in method is from String to a date type (e.g. {@link Date}) * or vice versa. @@ -45,6 +39,8 @@ public interface ConversionContext { String getNumberFormat(); + String getLocale(); + TypeFactory getTypeFactory(); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidationResult.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidationResult.java index 4409d50eab..a005b17a6d 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidationResult.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidationResult.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -56,7 +43,7 @@ public boolean isValid() { * * @param messager the messager to print the error message to * @param element the element that had the error - * @param annotation the mirror of the annotation that had an error + * @param annotation the positionHint of the annotation that had an error * @param value the value of the annotation that had an error */ public void printErrorMessage(FormattingMessager messager, Element element, AnnotationMirror annotation, diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidator.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidator.java index 9c2b4dee67..a502601fcb 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidator.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactory.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactory.java index cee6a19874..4d54f3c3e9 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactory.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactory.java @@ -1,28 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZonedDateTime; -import org.mapstruct.ap.internal.util.JavaTimeConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.XmlConstants; @@ -71,13 +61,8 @@ else if ( isJodaDateTimeSupposed( sourceType, targetType ) ) { dateFormatValidator = new JodaTimeDateFormatValidator(); } else { - dateFormatValidator = new DateFormatValidator() { - @Override - public DateFormatValidationResult validate(String dateFormat) { - return new DateFormatValidationResult( true, Message.GENERAL_UNSUPPORTED_DATE_FORMAT_CHECK, - sourceType, targetType ); - } - }; + dateFormatValidator = dateFormat -> new DateFormatValidationResult( + true, Message.GENERAL_UNSUPPORTED_DATE_FORMAT_CHECK, sourceType, targetType ); } return dateFormatValidator; @@ -85,7 +70,7 @@ public DateFormatValidationResult validate(String dateFormat) { private static boolean isXmlGregorianCalendarSupposedToBeMapped(Type sourceType, Type targetType) { return typesEqualsOneOf( - sourceType, targetType, XmlConstants.JAVAX_XML_DATATYPE_XMLGREGORIAN_CALENDAR ); + sourceType, targetType, XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ); } private static boolean isJodaDateTimeSupposed(Type sourceType, Type targetType) { @@ -102,10 +87,11 @@ private static boolean isJava8DateTimeSupposed(Type sourceType, Type targetType) return typesEqualsOneOf( sourceType, targetType, - JavaTimeConstants.LOCAL_DATE_FQN, - JavaTimeConstants.LOCAL_TIME_FQN, - JavaTimeConstants.LOCAL_DATE_TIME_FQN, - JavaTimeConstants.ZONED_DATE_TIME_FQN ); + LocalDate.class.getCanonicalName(), + LocalTime.class.getCanonicalName(), + LocalDateTime.class.getCanonicalName(), + ZonedDateTime.class.getCanonicalName() + ); } private static boolean isJavaUtilDateSupposed(Type sourceType, Type targetType) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DefaultConversionContext.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DefaultConversionContext.java index d1af4e85ef..4e5eed47a8 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/DefaultConversionContext.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/DefaultConversionContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -34,10 +21,11 @@ public class DefaultConversionContext implements ConversionContext { private final FormattingParameters formattingParameters; private final String dateFormat; private final String numberFormat; + private final String locale; private final TypeFactory typeFactory; public DefaultConversionContext(TypeFactory typeFactory, FormattingMessager messager, Type sourceType, - Type targetType, FormattingParameters formattingParameters) { + Type targetType, FormattingParameters formattingParameters) { this.typeFactory = typeFactory; this.messager = messager; this.sourceType = sourceType; @@ -45,6 +33,7 @@ public DefaultConversionContext(TypeFactory typeFactory, FormattingMessager mess this.formattingParameters = formattingParameters; this.dateFormat = this.formattingParameters.getDate(); this.numberFormat = this.formattingParameters.getNumber(); + this.locale = this.formattingParameters.getLocale(); validateDateFormat(); } @@ -72,11 +61,21 @@ public Type getTargetType() { return targetType; } + @Override + public Type getSourceType() { + return sourceType; + } + @Override public String getNumberFormat() { return numberFormat; } + @Override + public String getLocale() { + return locale != null ? locale.toString() : null; + } + @Override public String getDateFormat() { return dateFormat; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/FieldReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FieldReference.java new file mode 100644 index 0000000000..bf1f5be445 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FieldReference.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.common; + +import java.util.Map; + +/** + * reference used by BuiltInMethod/HelperMethod to create an additional field in the mapper. + */ +public interface FieldReference { + + /** + * + * @return variable name of the field + */ + String getVariableName(); + + /** + * + * @return type of the field + */ + Type getType(); + + /** + * @return additional template parameters + */ + default Map getTemplateParameter() { + return null; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/FinalField.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FinalField.java new file mode 100644 index 0000000000..c3e1ef1f39 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FinalField.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.common; + +/** + * A mapper instance field, initialized as null + * + * @author Sjaak Derksen + */ +public class FinalField implements FieldReference { + + private final Type type; + private String variableName; + + public FinalField(Type type, String variableName) { + this.type = type; + this.variableName = variableName; + } + + @Override + public String getVariableName() { + return variableName; + } + + @Override + public Type getType() { + return type; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/FormattingParameters.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FormattingParameters.java index 57428684fb..7ef818630a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/FormattingParameters.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/FormattingParameters.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -23,26 +10,29 @@ import javax.lang.model.element.Element; /** + * Represent information about the configured formatting. * * @author Sjaak Derksen */ public class FormattingParameters { - public static final FormattingParameters EMPTY = new FormattingParameters( null, null, null, null, null ); + public static final FormattingParameters EMPTY = new FormattingParameters( null, null, null, null, null, null ); private final String date; private final String number; private final AnnotationMirror mirror; private final AnnotationValue dateAnnotationValue; private final Element element; + private final String locale; public FormattingParameters(String date, String number, AnnotationMirror mirror, - AnnotationValue dateAnnotationValue, Element element) { + AnnotationValue dateAnnotationValue, Element element, String locale) { this.date = date; this.number = number; this.mirror = mirror; this.dateAnnotationValue = dateAnnotationValue; this.element = element; + this.locale = locale; } public String getDate() { @@ -64,4 +54,8 @@ public AnnotationValue getDateAnnotationValue() { public Element getElement() { return element; } + + public String getLocale() { + return locale; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ImplementationType.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ImplementationType.java index 15fb300b99..af8c7ecfb3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ImplementationType.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ImplementationType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -29,23 +16,34 @@ public class ImplementationType { private final Type type; private final boolean initialCapacityConstructor; private final boolean loadFactorAdjustment; + private final String factoryMethodName; - private ImplementationType(Type type, boolean initialCapacityConstructor, boolean loadFactorAdjustment) { + private ImplementationType( + Type type, + boolean initialCapacityConstructor, + boolean loadFactorAdjustment, + String factoryMethodName + ) { this.type = type; this.initialCapacityConstructor = initialCapacityConstructor; this.loadFactorAdjustment = loadFactorAdjustment; + this.factoryMethodName = factoryMethodName; } public static ImplementationType withDefaultConstructor(Type type) { - return new ImplementationType( type, false, false ); + return new ImplementationType( type, false, false, null ); } public static ImplementationType withInitialCapacity(Type type) { - return new ImplementationType( type, true, false ); + return new ImplementationType( type, true, false, null ); } public static ImplementationType withLoadFactorAdjustment(Type type) { - return new ImplementationType( type, true, true ); + return new ImplementationType( type, true, true, null ); + } + + public static ImplementationType withFactoryMethod(Type type, String factoryMethodName) { + return new ImplementationType( type, true, false, factoryMethodName ); } /** @@ -57,7 +55,7 @@ public static ImplementationType withLoadFactorAdjustment(Type type) { * @return a new implementation type with the given {@code type} */ public ImplementationType createNew(Type type) { - return new ImplementationType( type, initialCapacityConstructor, loadFactorAdjustment ); + return new ImplementationType( type, initialCapacityConstructor, loadFactorAdjustment, factoryMethodName ); } /** @@ -84,4 +82,8 @@ public boolean hasInitialCapacityConstructor() { public boolean isLoadFactorAdjustment() { return loadFactorAdjustment; } + + public String getFactoryMethodName() { + return factoryMethodName; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ModelElement.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ModelElement.java index 4d2e77b1c0..26d1067489 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ModelElement.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ModelElement.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/NegatePresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/NegatePresenceCheck.java new file mode 100644 index 0000000000..78357affb8 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/NegatePresenceCheck.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.common; + +import java.util.Objects; +import java.util.Set; + +/** + * A {@link PresenceCheck} that negates the result of another presence check. + * + * @author Filip Hrisafov + */ +public class NegatePresenceCheck extends ModelElement implements PresenceCheck { + + private final PresenceCheck presenceCheck; + + public NegatePresenceCheck(PresenceCheck presenceCheck) { + this.presenceCheck = presenceCheck; + } + + public PresenceCheck getPresenceCheck() { + return presenceCheck; + } + + @Override + public Set getImportTypes() { + return presenceCheck.getImportTypes(); + } + + @Override + public PresenceCheck negate() { + return presenceCheck; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + NegatePresenceCheck that = (NegatePresenceCheck) o; + return Objects.equals( presenceCheck, that.presenceCheck ); + } + + @Override + public int hashCode() { + return Objects.hash( presenceCheck ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/NewInstanceCreation.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/NewInstanceCreation.java new file mode 100644 index 0000000000..a91d7242cb --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/NewInstanceCreation.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.common; + +import java.util.Set; + +/** + * Model element representing the head of a {@code new T<>(...)} expression. It always renders the diamond + * operator for generic types, leaving any type-argument inference to the surrounding Java context. + *

    + * The caller is responsible for emitting the parenthesised argument list after the model. + *

    + * Imports contributed by this element only include the raw constructor type, not its type parameters: the + * generated source never references the parameter classes through this expression, so they are not needed + * here. If the surrounding code references a type parameter elsewhere (e.g. in a variable declaration or a + * method signature), that reference contributes its own imports through its own model element. + * + * @author Filip Hrisafov + */ +public class NewInstanceCreation extends ModelElement { + + private final Type type; + private final Type rawType; + + private NewInstanceCreation(Type type) { + this.type = type; + this.rawType = type.asRawType(); + } + + /** + * Creates a {@link NewInstanceCreation} for the given target type. If the target has an implementation + * type (e.g. {@code Collection} -> {@code ArrayList}), the implementation type is used. + * + * @param targetType the target type to be instantiated; must not be {@code null} + * @return a new model + */ + public static NewInstanceCreation forType(Type targetType) { + Type effective = targetType.getImplementationType() != null + ? targetType.getImplementationType() + : targetType; + return new NewInstanceCreation( effective ); + } + + public Type getType() { + return type; + } + + public Type getRawType() { + return rawType; + } + + public boolean isGeneric() { + return !type.getTypeParameters().isEmpty(); + } + + @Override + public Set getImportTypes() { + return rawType.getImportTypes(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Parameter.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Parameter.java index 98fb5dab56..c5091869a6 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Parameter.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Parameter.java @@ -1,32 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; -import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Set; - +import java.util.stream.Collectors; +import javax.lang.model.element.Element; import javax.lang.model.element.VariableElement; -import org.mapstruct.ap.internal.prism.ContextPrism; -import org.mapstruct.ap.internal.prism.MappingTargetPrism; -import org.mapstruct.ap.internal.prism.TargetTypePrism; +import org.mapstruct.ap.internal.gem.ContextGem; +import org.mapstruct.ap.internal.gem.MappingTargetGem; +import org.mapstruct.ap.internal.gem.SourcePropertyNameGem; +import org.mapstruct.ap.internal.gem.TargetPropertyNameGem; +import org.mapstruct.ap.internal.gem.TargetTypeGem; import org.mapstruct.ap.internal.util.Collections; /** @@ -36,24 +26,57 @@ */ public class Parameter extends ModelElement { + private final Element element; private final String name; private final String originalName; private final Type type; private final boolean mappingTarget; private final boolean targetType; private final boolean mappingContext; + private final boolean sourcePropertyName; + private final boolean targetPropertyName; - private Parameter(String name, Type type, boolean mappingTarget, boolean targetType, boolean mappingContext) { - this.name = name; + private final boolean varArgs; + + private Parameter(Element element, Type type, boolean varArgs) { + this.element = element; + this.name = element.getSimpleName().toString(); this.originalName = name; this.type = type; + this.mappingTarget = MappingTargetGem.instanceOn( element ) != null; + this.targetType = TargetTypeGem.instanceOn( element ) != null; + this.mappingContext = ContextGem.instanceOn( element ) != null; + this.sourcePropertyName = SourcePropertyNameGem.instanceOn( element ) != null; + this.targetPropertyName = TargetPropertyNameGem.instanceOn( element ) != null; + this.varArgs = varArgs; + } + + private Parameter(String name, String originalName, Type type, boolean mappingTarget, boolean targetType, + boolean mappingContext, + boolean sourcePropertyName, boolean targetPropertyName, + boolean varArgs) { + this.element = null; + this.name = name; + this.originalName = originalName; + this.type = type; this.mappingTarget = mappingTarget; this.targetType = targetType; this.mappingContext = mappingContext; + this.sourcePropertyName = sourcePropertyName; + this.targetPropertyName = targetPropertyName; + this.varArgs = varArgs; } public Parameter(String name, Type type) { - this( name, type, false, false, false ); + this( name, name, type ); + } + + public Parameter(String name, String originalName, Type type) { + this( name, originalName, type, false, false, false, false, false, false ); + } + + public Element getElement() { + return element; } public String getName() { @@ -74,10 +97,20 @@ public boolean isMappingTarget() { @Override public String toString() { + return String.format( format(), type ); + } + + public String describe() { + return String.format( format(), type.describe() ); + } + + private String format() { return ( mappingTarget ? "@MappingTarget " : "" ) + ( targetType ? "@TargetType " : "" ) + ( mappingContext ? "@Context " : "" ) - + type.toString() + " " + name; + + ( sourcePropertyName ? "@SourcePropertyName " : "" ) + + ( targetPropertyName ? "@TargetPropertyName " : "" ) + + "%s " + name; } @Override @@ -93,6 +126,40 @@ public boolean isMappingContext() { return mappingContext; } + public boolean isTargetPropertyName() { + return targetPropertyName; + } + + public boolean isSourcePropertyName() { + return sourcePropertyName; + } + + public boolean isVarArgs() { + return varArgs; + } + + public boolean isSourceParameter() { + return !isMappingTarget() && + !isTargetType() && + !isMappingContext() && + !isSourcePropertyName() && + !isTargetPropertyName(); + } + + public Parameter withName(String name) { + return new Parameter( + name, + this.name, + type, + mappingTarget, + targetType, + mappingContext, + sourcePropertyName, + targetPropertyName, + varArgs + ); + } + @Override public int hashCode() { int result = name != null ? name.hashCode() : 0; @@ -111,29 +178,33 @@ public boolean equals(Object o) { Parameter parameter = (Parameter) o; - if ( name != null ? !name.equals( parameter.name ) : parameter.name != null ) { + if ( !Objects.equals( name, parameter.name ) ) { return false; } - return type != null ? type.equals( parameter.type ) : parameter.type == null; + return Objects.equals( type, parameter.type ); } - public static Parameter forElementAndType(VariableElement element, Type parameterType) { + public static Parameter forElementAndType(VariableElement element, Type parameterType, boolean isVarArgs) { return new Parameter( - element.getSimpleName().toString(), + element, parameterType, - MappingTargetPrism.getInstanceOn( element ) != null, - TargetTypePrism.getInstanceOn( element ) != null, - ContextPrism.getInstanceOn( element ) != null ); + isVarArgs + ); } public static Parameter forForgedMappingTarget(Type parameterType) { return new Parameter( + "mappingTarget", "mappingTarget", parameterType, true, false, - false); + false, + false, + false, + false + ); } /** @@ -141,15 +212,20 @@ public static Parameter forForgedMappingTarget(Type parameterType) { * @return the parameters from the given list that are considered 'source parameters' */ public static List getSourceParameters(List parameters) { - List sourceParameters = new ArrayList( parameters.size() ); - - for ( Parameter parameter : parameters ) { - if ( !parameter.isMappingTarget() && !parameter.isTargetType() && !parameter.isMappingContext() ) { - sourceParameters.add( parameter ); - } - } + return parameters.stream().filter( Parameter::isSourceParameter ).collect( Collectors.toList() ); + } - return sourceParameters; + /** + * @param parameters the parameters to scan + * @param sourceParameterName the source parameter name to match + * @return the parameters from the given list that are considered 'source parameters' + */ + public static Parameter getSourceParameter(List parameters, String sourceParameterName) { + return parameters.stream() + .filter( Parameter::isSourceParameter ) + .filter( parameter -> parameter.getName().equals( sourceParameterName ) ) + .findAny() + .orElse( null ); } /** @@ -157,34 +233,23 @@ public static List getSourceParameters(List parameters) { * @return the parameters from the given list that are marked as 'mapping context parameters' */ public static List getContextParameters(List parameters) { - List contextParameters = new ArrayList( parameters.size() ); - - for ( Parameter parameter : parameters ) { - if ( parameter.isMappingContext() ) { - contextParameters.add( parameter ); - } - } - - return contextParameters; + return parameters.stream().filter( Parameter::isMappingContext ).collect( Collectors.toList() ); } public static Parameter getMappingTargetParameter(List parameters) { - for ( Parameter parameter : parameters ) { - if ( parameter.isMappingTarget() ) { - return parameter; - } - } - - return null; + return parameters.stream().filter( Parameter::isMappingTarget ).findAny().orElse( null ); } public static Parameter getTargetTypeParameter(List parameters) { - for ( Parameter parameter : parameters ) { - if ( parameter.isTargetType() ) { - return parameter; - } - } + return parameters.stream().filter( Parameter::isTargetType ).findAny().orElse( null ); + } - return null; + public static Parameter getSourcePropertyNameParameter(List parameters) { + return parameters.stream().filter( Parameter::isSourcePropertyName ).findAny().orElse( null ); } + + public static Parameter getTargetPropertyNameParameter(List parameters) { + return parameters.stream().filter( Parameter::isTargetPropertyName ).findAny().orElse( null ); + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ParameterBinding.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ParameterBinding.java index 9cfdfcaeca..c1a594c73a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/ParameterBinding.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/ParameterBinding.java @@ -1,25 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.EnumSet; import java.util.List; import java.util.Set; @@ -32,18 +21,14 @@ public class ParameterBinding { private final Type type; private final String variableName; - private final boolean targetType; - private final boolean mappingTarget; - private final boolean mappingContext; private final SourceRHS sourceRHS; + private final Collection bindingTypes; - private ParameterBinding(Type parameterType, String variableName, boolean mappingTarget, boolean targetType, - boolean mappingContext, SourceRHS sourceRHS) { + private ParameterBinding(Type parameterType, String variableName, Collection bindingTypes, + SourceRHS sourceRHS) { this.type = parameterType; this.variableName = variableName; - this.targetType = targetType; - this.mappingTarget = mappingTarget; - this.mappingContext = mappingContext; + this.bindingTypes = bindingTypes; this.sourceRHS = sourceRHS; } @@ -54,25 +39,47 @@ public String getVariableName() { return variableName; } + public boolean isSourceParameter() { + return bindingTypes.contains( BindingType.PARAMETER ); + } + /** * @return {@code true}, if the parameter being bound is a {@code @TargetType} parameter. */ public boolean isTargetType() { - return targetType; + return bindingTypes.contains( BindingType.TARGET_TYPE ); } /** * @return {@code true}, if the parameter being bound is a {@code @MappingTarget} parameter. */ public boolean isMappingTarget() { - return mappingTarget; + return bindingTypes.contains( BindingType.MAPPING_TARGET ); } /** * @return {@code true}, if the parameter being bound is a {@code @MappingContext} parameter. */ public boolean isMappingContext() { - return mappingContext; + return bindingTypes.contains( BindingType.CONTEXT ); + } + + public boolean isForSourceRhs() { + return bindingTypes.contains( BindingType.SOURCE_RHS ); + } + + /** + * @return {@code true}, if the parameter being bound is a {@code @SourcePropertyName} parameter. + */ + public boolean isSourcePropertyName() { + return bindingTypes.contains( BindingType.SOURCE_PROPERTY_NAME ); + } + + /** + * @return {@code true}, if the parameter being bound is a {@code @TargetPropertyName} parameter. + */ + public boolean isTargetPropertyName() { + return bindingTypes.contains( BindingType.TARGET_PROPERTY_NAME ); } /** @@ -90,7 +97,7 @@ public SourceRHS getSourceRHS() { } public Set getImportTypes() { - if ( targetType ) { + if ( isTargetType() ) { return type.getImportTypes(); } @@ -106,30 +113,82 @@ public Set getImportTypes() { * @return a parameter binding reflecting the given parameter as being used as argument for a method call */ public static ParameterBinding fromParameter(Parameter parameter) { + EnumSet bindingTypes = EnumSet.of( BindingType.PARAMETER ); + if ( parameter.isMappingTarget() ) { + bindingTypes.add( BindingType.MAPPING_TARGET ); + } + + if ( parameter.isTargetType() ) { + bindingTypes.add( BindingType.TARGET_TYPE ); + } + + if ( parameter.isMappingContext() ) { + bindingTypes.add( BindingType.CONTEXT ); + } + + if ( parameter.isSourcePropertyName() ) { + bindingTypes.add( BindingType.SOURCE_PROPERTY_NAME ); + } + + if ( parameter.isTargetPropertyName() ) { + bindingTypes.add( BindingType.TARGET_PROPERTY_NAME ); + } + return new ParameterBinding( parameter.getType(), parameter.getName(), - parameter.isMappingTarget(), - parameter.isTargetType(), - parameter.isMappingContext(), + bindingTypes, null ); } public static List fromParameters(List parameters) { - List result = new ArrayList( parameters.size() ); + List result = new ArrayList<>( parameters.size() ); for ( Parameter param : parameters ) { result.add( fromParameter( param ) ); } return result; } + public static ParameterBinding fromTypeAndName(Type parameterType, String parameterName) { + return new ParameterBinding( + parameterType, + parameterName, + Collections.emptySet(), + null + ); + } + /** * @param classTypeOf the type representing {@code Class} for the target type {@code X} * @return a parameter binding representing a target type parameter */ public static ParameterBinding forTargetTypeBinding(Type classTypeOf) { - return new ParameterBinding( classTypeOf, null, false, true, false, null ); + return new ParameterBinding( classTypeOf, null, Collections.singleton( BindingType.TARGET_TYPE ), null ); + } + + /** + * @return a parameter binding representing a target property name parameter + */ + public static ParameterBinding forTargetPropertyNameBinding(Type classTypeOf) { + return new ParameterBinding( + classTypeOf, + null, + Collections.singleton( BindingType.TARGET_PROPERTY_NAME ), + null + ); + } + + /** + * @return a parameter binding representing a source property name parameter + */ + public static ParameterBinding forSourcePropertyNameBinding(Type classTypeOf) { + return new ParameterBinding( + classTypeOf, + null, + Collections.singleton( BindingType.SOURCE_PROPERTY_NAME ), + null + ); } /** @@ -137,7 +196,7 @@ public static ParameterBinding forTargetTypeBinding(Type classTypeOf) { * @return a parameter binding representing a mapping target parameter */ public static ParameterBinding forMappingTargetBinding(Type resultType) { - return new ParameterBinding( resultType, null, true, false, false, null ); + return new ParameterBinding( resultType, null, Collections.singleton( BindingType.MAPPING_TARGET ), null ); } /** @@ -145,10 +204,27 @@ public static ParameterBinding forMappingTargetBinding(Type resultType) { * @return a parameter binding representing a mapping source type */ public static ParameterBinding forSourceTypeBinding(Type sourceType) { - return new ParameterBinding( sourceType, null, false, false, false, null ); + return new ParameterBinding( sourceType, null, Collections.singleton( BindingType.SOURCE_TYPE ), null ); } public static ParameterBinding fromSourceRHS(SourceRHS sourceRHS) { - return new ParameterBinding( sourceRHS.getSourceType(), null, false, false, false, sourceRHS ); + return new ParameterBinding( + sourceRHS.getSourceType(), + null, + Collections.singleton( BindingType.SOURCE_RHS ), + sourceRHS + ); + } + + enum BindingType { + PARAMETER, + FROM_TYPE_AND_NAME, + TARGET_TYPE, + TARGET_PROPERTY_NAME, + SOURCE_PROPERTY_NAME, + MAPPING_TARGET, + CONTEXT, + SOURCE_TYPE, + SOURCE_RHS } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/PresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/PresenceCheck.java new file mode 100644 index 0000000000..ec286480d9 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/PresenceCheck.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.common; + +import java.util.Set; + +/** + * Marker interface for presence checks. + * + * @author Filip Hrisafov + */ +public interface PresenceCheck { + + /** + * returns all types required as import by the presence check. + * + * @return imported types + */ + Set getImportTypes(); + + PresenceCheck negate(); + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/SourceRHS.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/SourceRHS.java index 61de3548c1..b4d422c797 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/SourceRHS.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/SourceRHS.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -22,6 +9,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.stream.Stream; import org.mapstruct.ap.internal.util.Strings; @@ -39,9 +27,10 @@ public class SourceRHS extends ModelElement implements Assignment { private final String sourceReference; private final Type sourceType; private String sourceLocalVarName; + private String sourceLoopVarName; private final Set existingVariableNames; private final String sourceErrorMessagePart; - private final String sourcePresenceCheckerReference; + private PresenceCheck sourcePresenceCheckerReference; private boolean useElementAsSourceTypeForMatching = false; private final String sourceParameterName; @@ -50,7 +39,7 @@ public SourceRHS(String sourceReference, Type sourceType, Set existingVa this( sourceReference, sourceReference, null, sourceType, existingVariableNames, sourceErrorMessagePart ); } - public SourceRHS(String sourceParameterName, String sourceReference, String sourcePresenceCheckerReference, + public SourceRHS(String sourceParameterName, String sourceReference, PresenceCheck sourcePresenceCheckerReference, Type sourceType, Set existingVariableNames, String sourceErrorMessagePart ) { this.sourceReference = sourceReference; this.sourceType = sourceType; @@ -71,18 +60,22 @@ public boolean isSourceReferenceParameter() { } @Override - public String getSourcePresenceCheckerReference() { + public PresenceCheck getSourcePresenceCheckerReference() { return sourcePresenceCheckerReference; } + public void setSourcePresenceCheckerReference(PresenceCheck sourcePresenceCheckerReference) { + this.sourcePresenceCheckerReference = sourcePresenceCheckerReference; + } + @Override public Type getSourceType() { return sourceType; } @Override - public String createLocalVarName(String desiredName) { - String result = Strings.getSaveVariableName( desiredName, existingVariableNames ); + public String createUniqueVarName(String desiredName) { + String result = Strings.getSafeVariableName( desiredName, existingVariableNames ); existingVariableNames.add( result ); return result; } @@ -97,8 +90,20 @@ public void setSourceLocalVarName(String sourceLocalVarName) { this.sourceLocalVarName = sourceLocalVarName; } + public String getSourceLoopVarName() { + return sourceLoopVarName; + } + + public void setSourceLoopVarName(String sourceLoopVarName) { + this.sourceLoopVarName = sourceLoopVarName; + } + @Override public Set getImportTypes() { + if ( sourcePresenceCheckerReference != null ) { + return sourcePresenceCheckerReference.getImportTypes(); + } + return Collections.emptySet(); } @@ -137,8 +142,21 @@ public String getSourceErrorMessagePart() { * @return the source type to be used in the matching process. */ public Type getSourceTypeForMatching() { - return useElementAsSourceTypeForMatching && sourceType.isCollectionType() ? - first( sourceType.determineTypeArguments( Collection.class ) ) : sourceType; + if ( useElementAsSourceTypeForMatching ) { + if ( sourceType.isCollectionType() ) { + return first( sourceType.determineTypeArguments( Collection.class ) ); + } + else if ( sourceType.isStreamType() ) { + return first( sourceType.determineTypeArguments( Stream.class ) ); + } + else if ( sourceType.isArrayType() ) { + return sourceType.getComponentType(); + } + else if ( sourceType.isIterableType() ) { + return first( sourceType.determineTypeArguments( Iterable.class ) ); + } + } + return sourceType; } /** diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java index a1724f0e25..0c02870352 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/Type.java @@ -1,58 +1,77 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.Deque; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import javax.lang.model.element.Name; +import javax.lang.model.element.NestingKind; import javax.lang.model.element.TypeElement; import javax.lang.model.element.VariableElement; +import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.IntersectionType; +import javax.lang.model.type.PrimitiveType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; import javax.lang.model.type.WildcardType; import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; +import javax.lang.model.util.SimpleTypeVisitor8; + +import kotlin.Metadata; +import kotlin.metadata.Attributes; +import kotlin.metadata.KmClass; +import kotlin.metadata.KmConstructor; +import kotlin.metadata.Modality; +import kotlin.metadata.jvm.JvmExtensionsKt; +import kotlin.metadata.jvm.JvmMethodSignature; +import kotlin.metadata.jvm.KotlinClassMetadata; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; import org.mapstruct.ap.internal.util.AccessorNamingUtils; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.Executables; import org.mapstruct.ap.internal.util.Filters; +import org.mapstruct.ap.internal.util.JSpecifyConstants; +import org.mapstruct.ap.internal.util.JavaStreamConstants; +import org.mapstruct.ap.internal.util.NativeTypes; import org.mapstruct.ap.internal.util.Nouns; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; -import org.mapstruct.ap.spi.BuilderInfo; - +import org.mapstruct.ap.internal.util.accessor.AccessorType; +import org.mapstruct.ap.internal.util.accessor.ElementAccessor; +import org.mapstruct.ap.internal.util.accessor.MapValueAccessor; +import org.mapstruct.ap.internal.util.accessor.PresenceCheckAccessor; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; +import org.mapstruct.ap.internal.util.kotlin.KotlinMetadata; + +import static java.util.Collections.emptyList; import static org.mapstruct.ap.internal.util.Collections.first; -import org.mapstruct.ap.internal.util.NativeTypes; /** * Represents (a reference to) the type of a bean property, parameter etc. Types are managed per generated source file. @@ -63,11 +82,35 @@ * through {@link TypeFactory}. * * @author Gunnar Morling + * @author Filip Hrisafov */ public class Type extends ModelElement implements Comparable { + private static final Method SEALED_PERMITTED_SUBCLASSES_METHOD; + private static final boolean KOTLIN_METADATA_JVM_PRESENT; + + static { + Method permittedSubclassesMethod; + try { + permittedSubclassesMethod = TypeElement.class.getMethod( "getPermittedSubclasses" ); + } + catch ( NoSuchMethodException e ) { + permittedSubclassesMethod = null; + } + SEALED_PERMITTED_SUBCLASSES_METHOD = permittedSubclassesMethod; + + boolean kotlinMetadataJvmPresent; + try { + Class.forName( "kotlin.metadata.jvm.KotlinClassMetadata", false, ModelElement.class.getClassLoader() ); + kotlinMetadataJvmPresent = true; + } + catch ( ClassNotFoundException e ) { + kotlinMetadataJvmPresent = false; + } + KOTLIN_METADATA_JVM_PRESENT = kotlinMetadataJvmPresent; + } - private final Types typeUtils; - private final Elements elementUtils; + private final TypeUtils typeUtils; + private final ElementUtils elementUtils; private final TypeFactory typeFactory; private final AccessorNamingUtils accessorNaming; @@ -77,10 +120,11 @@ public class Type extends ModelElement implements Comparable { private final ImplementationType implementationType; private final Type componentType; - private final BuilderType builderType; + private final Type topLevelType; private final String packageName; private final String name; + private final String nameWithTopLevelTypeName; private final String qualifiedName; private final boolean isInterface; @@ -88,35 +132,53 @@ public class Type extends ModelElement implements Comparable { private final boolean isIterableType; private final boolean isCollectionType; private final boolean isMapType; - private final boolean isImported; private final boolean isVoid; private final boolean isStream; private final boolean isLiteral; + private final boolean loggingVerbose; + private final List enumConstants; - private Map readAccessors = null; - private Map presenceCheckers = null; + private final Map toBeImportedTypes; + private final Map notToBeImportedTypes; + private Boolean isToBeImported; + + private Map readAccessors = null; + private Map presenceCheckers = null; + + private List allMethods = null; + private List allFields = null; + private List recordComponents = null; - private List allAccessors = null; private List setters = null; private List adders = null; private List alternativeTargetAccessors = null; private Type boundingBase = null; + private List boundTypes = null; + + private Type boxedEquivalent = null; - private Boolean hasEmptyAccessibleContructor; + private Boolean hasAccessibleConstructor; + private Boolean isNullMarked; + private KotlinMetadata kotlinMetadata; + private boolean kotlinMetadataInitialized; + + private final Filters filters; //CHECKSTYLE:OFF - public Type(Types typeUtils, Elements elementUtils, TypeFactory typeFactory, + public Type(TypeUtils typeUtils, ElementUtils elementUtils, TypeFactory typeFactory, AccessorNamingUtils accessorNaming, TypeMirror typeMirror, TypeElement typeElement, List typeParameters, ImplementationType implementationType, Type componentType, - BuilderInfo builderInfo, String packageName, String name, String qualifiedName, boolean isInterface, boolean isEnumType, boolean isIterableType, - boolean isCollectionType, boolean isMapType, boolean isStreamType, boolean isImported, - boolean isLiteral ) { + boolean isCollectionType, boolean isMapType, boolean isStreamType, + Map toBeImportedTypes, + Map notToBeImportedTypes, + Boolean isToBeImported, + boolean isLiteral, boolean loggingVerbose) { this.typeUtils = typeUtils; this.elementUtils = elementUtils; @@ -139,12 +201,11 @@ public Type(Types typeUtils, Elements elementUtils, TypeFactory typeFactory, this.isCollectionType = isCollectionType; this.isMapType = isMapType; this.isStream = isStreamType; - this.isImported = isImported; this.isVoid = typeMirror.getKind() == TypeKind.VOID; this.isLiteral = isLiteral; if ( isEnumType ) { - enumConstants = new ArrayList(); + enumConstants = new ArrayList<>(); for ( Element element : typeElement.getEnclosedElements() ) { // #162: The check for visibility shouldn't be required, but the Eclipse compiler implementation @@ -159,7 +220,25 @@ public Type(Types typeUtils, Elements elementUtils, TypeFactory typeFactory, enumConstants = Collections.emptyList(); } - this.builderType = BuilderType.create( builderInfo, this, this.typeFactory, this.typeUtils ); + this.isToBeImported = isToBeImported; + this.toBeImportedTypes = toBeImportedTypes; + this.notToBeImportedTypes = notToBeImportedTypes; + this.filters = new Filters( accessorNaming, typeUtils, typeMirror ); + + this.loggingVerbose = loggingVerbose; + + TypeElement typeElementForTopLevel; + if ( Boolean.TRUE.equals( isToBeImported ) ) { + // If the is to be imported is explicitly set to true then we shouldn't look for the top level type + typeElementForTopLevel = null; + } + else { + // The top level type for an array type is the top level type of the component type + typeElementForTopLevel = + this.componentType == null ? this.typeElement : this.componentType.getTypeElement(); + } + this.topLevelType = topLevelType( typeElementForTopLevel, this.typeFactory ); + this.nameWithTopLevelTypeName = nameWithTopLevelTypeName( typeElementForTopLevel, this.name ); } //CHECKSTYLE:ON @@ -180,12 +259,40 @@ public String getName() { } /** - * String that could be used in generated code to reference to this {@link Type}. + * Returns a String that could be used in generated code to reference to this {@link Type}.
    + *

    + * The first time a name is referred-to it will be marked as to be imported. For instance + * {@code LocalDateTime} can be one of {@code java.time.LocalDateTime} and {@code org.joda.LocalDateTime}) + *

    + * If the {@code java.time} variant is referred to first, the {@code java.time.LocalDateTime} will be imported + * and the {@code org.joda} variant will be referred to with its FQN. + *

    + * If the type is nested and its top level type is to be imported + * then the name including its top level type will be returned. * - * @return Just the name if this {@link Type} will be imported, otherwise the fully-qualified name. + * @return Just the name if this {@link Type} will be imported, the name up to the top level {@link Type} + * (if the top level type is important, otherwise the fully-qualified name. */ - public String getReferenceName() { - return isImported ? name : qualifiedName; + public String createReferenceName() { + if ( isToBeImported() ) { + // isToBeImported() returns true for arrays. + // Therefore, we need to check the top level type when creating the reference + if ( isTopLevelTypeToBeImported() ) { + return nameWithTopLevelTypeName != null ? nameWithTopLevelTypeName : name; + } + + return name; + } + + if ( shouldUseSimpleName() ) { + return name; + } + + if ( isTopLevelTypeToBeImported() && nameWithTopLevelTypeName != null ) { + return nameWithTopLevelTypeName; + } + + return qualifiedName; } public List getTypeParameters() { @@ -196,18 +303,6 @@ public Type getComponentType() { return componentType; } - public BuilderType getBuilderType() { - return builderType; - } - - /** - * The effective type that should be used when searching for getters / setters, creating new types etc - * @return the effective type for mappings - */ - public Type getEffectiveType() { - return builderType != null ? builderType.getBuilder() : this; - } - public boolean isPrimitive() { return typeMirror.getKind().isPrimitive(); } @@ -228,6 +323,57 @@ public boolean isAbstract() { return typeElement != null && typeElement.getModifiers().contains( Modifier.ABSTRACT ); } + public boolean isString() { + return String.class.getName().equals( getFullyQualifiedName() ); + } + + /** + * Whether this type is within a JSpecify {@code @NullMarked} scope. Walks the enclosing-element + * chain (this type, outer classes, package) and returns at the first {@code @NullMarked} or + * {@code @NullUnmarked} encountered — the closest annotation wins. Module-level annotations + * are only reached when the compiler populates {@code PackageElement.getEnclosingElement()} + * with a {@link javax.lang.model.element.ModuleElement} (JPMS only). + *

    + * The result is memoized on this {@code Type} instance. {@link TypeFactory#getType} does not + * intern {@code Type} instances, so callers that invoke this repeatedly should cache the + * {@code Type} reference or the result. + * + * @return {@code true} if the closest enclosing annotation is {@code @NullMarked}; + * {@code false} if it is {@code @NullUnmarked} or if no such annotation was found + */ + public boolean isNullMarked() { + if ( isNullMarked == null ) { + isNullMarked = resolveNullMarked(); + } + return isNullMarked; + } + + private boolean resolveNullMarked() { + if ( typeElement == null ) { + return false; + } + Element current = typeElement; + while ( current != null ) { + for ( AnnotationMirror mirror : current.getAnnotationMirrors() ) { + Element annotationElement = mirror.getAnnotationType().asElement(); + if ( !( annotationElement instanceof TypeElement ) ) { + // Defensive: unresolved annotations (e.g. ErrorType during incremental + // builds) can produce a non-TypeElement. Skip instead of crashing. + continue; + } + String fqn = ( (TypeElement) annotationElement ).getQualifiedName().toString(); + if ( JSpecifyConstants.NULL_MARKED_FQN.equals( fqn ) ) { + return true; + } + if ( JSpecifyConstants.NULL_UNMARKED_FQN.equals( fqn ) ) { + return false; + } + } + current = current.getEnclosingElement(); + } + return false; + } + /** * @return this type's enum constants in case it is an enum, an empty list otherwise. */ @@ -278,6 +424,17 @@ public boolean isMapType() { return isMapType; } + private boolean hasStringMapSignature() { + if ( isMapType() ) { + List typeParameters = getTypeParameters(); + if ( typeParameters.size() == 2 && typeParameters.get( 0 ).isString() ) { + return true; + } + } + + return false; + } + public boolean isCollectionOrMapType() { return isCollectionType || isMapType; } @@ -286,10 +443,52 @@ public boolean isArrayType() { return componentType != null; } + private boolean isType(Class type) { + return type.getName().equals( getFullyQualifiedName() ); + } + + public boolean isOptionalType() { + return isType( Optional.class ) || isType( OptionalInt.class ) || isType( OptionalDouble.class ) || + isType( OptionalLong.class ); + } + + public Type getOptionalBaseType() { + if ( isType( Optional.class ) ) { + return getTypeParameters().get( 0 ); + } + + if ( isType( OptionalInt.class ) ) { + return typeFactory.getType( int.class ); + } + + if ( isType( OptionalDouble.class ) ) { + return typeFactory.getType( double.class ); + } + + if ( isType( OptionalLong.class ) ) { + return typeFactory.getType( long.class ); + } + + throw new IllegalStateException( "getOptionalBaseType should only be called for Optional types." ); + + } + public boolean isTypeVar() { return (typeMirror.getKind() == TypeKind.TYPEVAR); } + public boolean isIntersection() { + return typeMirror.getKind() == TypeKind.INTERSECTION; + } + + public boolean isJavaLangType() { + return packageName != null && packageName.startsWith( "java." ); + } + + public boolean isRecord() { + return typeElement.getKind().name().equals( "RECORD" ); + } + /** * Whether this type is a sub-type of {@link java.util.stream.Stream}. * @@ -299,7 +498,12 @@ public boolean isStreamType() { return isStream; } - public boolean isWildCardSuperBound() { + /** + * A wild card type can have two types of bounds (mutual exclusive): extends and super. + * + * @return true if the bound has a wild card super bound (e.g. {@code ? super Number}) + */ + public boolean hasSuperBound() { boolean result = false; if ( typeMirror.getKind() == TypeKind.WILDCARD ) { WildcardType wildcardType = (WildcardType) typeMirror; @@ -308,7 +512,12 @@ public boolean isWildCardSuperBound() { return result; } - public boolean isWildCardExtendsBound() { + /** + * A wild card type can have two types of bounds (mutual exclusive): extends and super. + * + * @return true if the bound has a wild card extends bound (e.g. {@code ? extends Number}) + */ + public boolean hasExtendsBound() { boolean result = false; if ( typeMirror.getKind() == TypeKind.WILDCARD ) { WildcardType wildcardType = (WildcardType) typeMirror; @@ -317,6 +526,40 @@ public boolean isWildCardExtendsBound() { return result; } + /** + * A type variable type can have two types of bounds (mutual exclusive): lower and upper. + * + * Note that its use is only permitted on a definition (not on the place where its used). For instance: + * {@code T map( T in)} + * + * @return true if the bound has a type variable lower bound (e.g. T super Number) + */ + public boolean hasLowerBound() { + boolean result = false; + if ( typeMirror.getKind() == TypeKind.TYPEVAR ) { + TypeVariable typeVarType = (TypeVariable) typeMirror; + result = typeVarType.getLowerBound() != null; + } + return result; + } + + /** + * A type variable type can have two types of bounds (mutual exclusive): lower and upper. + * + * Note that its use is only permitted on a definition (not on the place where its used). For instance: + * {@code> T map( T in)} + * + * @return true if the bound has a type variable upper bound (e.g. T extends Number) + */ + public boolean hasUpperBound() { + boolean result = false; + if ( typeMirror.getKind() == TypeKind.TYPEVAR ) { + TypeVariable typeVarType = (TypeVariable) typeMirror; + result = typeVarType.getUpperBound() != null; + } + return result; + } + public String getFullyQualifiedName() { return qualifiedName; } @@ -325,12 +568,12 @@ public String getFullyQualifiedName() { * @return The name of this type as to be used within import statements. */ public String getImportName() { - return isArrayType() ? TypeFactory.trimSimpleClassName( qualifiedName ) : qualifiedName; + return isArrayType() ? trimSimpleClassName( qualifiedName ) : qualifiedName; } @Override public Set getImportTypes() { - Set result = new HashSet(); + Set result = new HashSet<>(); if ( getTypeMirror().getKind() == TypeKind.DECLARED ) { result.add( this ); @@ -340,44 +583,61 @@ public Set getImportTypes() { result.addAll( componentType.getImportTypes() ); } + if ( topLevelType != null ) { + result.addAll( topLevelType.getImportTypes() ); + } + for ( Type parameter : typeParameters ) { result.addAll( parameter.getImportTypes() ); } - if ( ( isWildCardExtendsBound() || isWildCardSuperBound() ) && getTypeBound() != null ) { + if ( ( hasExtendsBound() || hasSuperBound() ) && getTypeBound() != null ) { result.addAll( getTypeBound().getImportTypes() ); } return result; } - /** - * Whether this type is imported by means of an import statement in the currently generated source file (meaning it - * can be referenced in the generated source using its simple name) or not (meaning it has to be referenced using - * the fully-qualified name). - * - * @return {@code true} if the type is imported, {@code false} otherwise. - */ - public boolean isImported() { - return isImported; + protected boolean isTopLevelTypeToBeImported() { + return topLevelType != null && topLevelType.isToBeImported(); } /** - * @param annotationTypeName the fully qualified name of the annotation type + * Whether this type is to be imported by means of an import statement in the currently generated source file + * (it can be referenced in the generated source using its simple name) or not (referenced using the FQN). * - * @return true, if the type is annotated with an annotation of the specified type (super-types are not inspected) + * @return {@code true} if the type is imported, {@code false} otherwise. */ - public boolean isAnnotatedWith(String annotationTypeName) { - List annotationMirrors = typeElement.getAnnotationMirrors(); + public boolean isToBeImported() { + if ( isToBeImported == null ) { + String trimmedName = trimSimpleClassName( name ); + if ( notToBeImportedTypes.containsKey( trimmedName ) ) { + isToBeImported = false; + return isToBeImported; + } + String trimmedQualifiedName = trimSimpleClassName( qualifiedName ); + String importedType = toBeImportedTypes.get( trimmedName ); - for ( AnnotationMirror mirror : annotationMirrors ) { - Name mirrorAnnotationName = ( (TypeElement) mirror.getAnnotationType().asElement() ).getQualifiedName(); - if ( mirrorAnnotationName.contentEquals( annotationTypeName ) ) { - return true; + isToBeImported = false; + if ( importedType != null ) { + if ( importedType.equals( trimmedQualifiedName ) ) { + isToBeImported = true; + } + } + else if ( typeElement == null || !typeElement.getNestingKind().isNested() ) { + toBeImportedTypes.put( trimmedName, trimmedQualifiedName ); + isToBeImported = true; } } + return isToBeImported; + } - return false; + private boolean shouldUseSimpleName() { + // Using trimSimpleClassName since the same is used in the isToBeImported() + // to check whether notToBeImportedTypes contains it + String trimmedName = trimSimpleClassName( name ); + String fqn = notToBeImportedTypes.get( trimmedName ); + return trimSimpleClassName( this.qualifiedName ).equals( fqn ); } public Type erasure() { @@ -391,7 +651,6 @@ public Type erasure() { typeParameters, implementationType, componentType, - builderType == null ? null : builderType.asBuilderInfo(), packageName, name, qualifiedName, @@ -401,8 +660,85 @@ public Type erasure() { isCollectionType, isMapType, isStream, - isImported, - isLiteral + toBeImportedTypes, + notToBeImportedTypes, + isToBeImported, + isLiteral, + loggingVerbose + ); + } + + public Type replaceSuperBoundWith( Type compare, Type replacement ) { + if ( typeParameters.isEmpty() ) { + return this; + } + List targetTypeParameters = compare.getTypeParameters(); + if ( targetTypeParameters.size() != typeParameters.size() ) { + return this; + } + TypeMirror replacementMirror = replacement.getTypeMirror(); + boolean noChange = true; + List bounds = new ArrayList<>( typeParameters.size() ); + TypeMirror[] mirrors = new TypeMirror[ typeParameters.size() ]; + for ( int x = 0; x < typeParameters.size(); x++ ) { + Type type = typeParameters.get( x ); + if ( !type.hasSuperBound() || type.isRawAssignableTo( targetTypeParameters.get( x ) ) ) { + bounds.add( type ); + mirrors[ x ] = type.getTypeMirror(); + } + else { + bounds.add( replacement ); + mirrors[x] = replacementMirror; + noChange = false; + } + } + + if ( noChange ) { + return this; + } + + TypeElement typeElementWithoutBounds; + Type componentTypeWithoutBounds; + TypeMirror typeMirrorWithoutBounds; + if ( this.componentType != null ) { + typeElementWithoutBounds = null; + componentTypeWithoutBounds = this.componentType.replaceSuperBoundWith( compare, replacement ); + typeMirrorWithoutBounds = typeUtils.getArrayType( componentTypeWithoutBounds.getTypeMirror() ); + } + else { + DeclaredType declaredType = typeUtils.getDeclaredType( + typeElement, + mirrors + ); + typeMirrorWithoutBounds = declaredType; + typeElementWithoutBounds = (TypeElement) declaredType.asElement(); + componentTypeWithoutBounds = null; + } + + return new Type( + typeUtils, + elementUtils, + typeFactory, + accessorNaming, + typeMirrorWithoutBounds, + typeElementWithoutBounds, + bounds, + implementationType, + componentTypeWithoutBounds, + packageName, + name, + qualifiedName, + isInterface, + isEnumType, + isIterableType, + isCollectionType, + isMapType, + isStream, + toBeImportedTypes, + notToBeImportedTypes, + isToBeImported, + isLiteral, + loggingVerbose ); } @@ -411,28 +747,41 @@ public Type withoutBounds() { return this; } - List bounds = new ArrayList( typeParameters.size() ); - List mirrors = new ArrayList( typeParameters.size() ); + List bounds = new ArrayList<>( typeParameters.size() ); + List mirrors = new ArrayList<>( typeParameters.size() ); for ( Type typeParameter : typeParameters ) { bounds.add( typeParameter.getTypeBound() ); mirrors.add( typeParameter.getTypeBound().getTypeMirror() ); } - DeclaredType declaredType = typeUtils.getDeclaredType( - typeElement, - mirrors.toArray( new TypeMirror[] {} ) - ); + TypeElement typeElementWithoutBounds; + Type componentTypeWithoutBounds; + TypeMirror typeMirrorWithoutBounds; + if ( this.componentType != null ) { + typeElementWithoutBounds = null; + componentTypeWithoutBounds = this.componentType.withoutBounds(); + typeMirrorWithoutBounds = typeUtils.getArrayType( componentTypeWithoutBounds.getTypeMirror() ); + } + else { + DeclaredType declaredType = typeUtils.getDeclaredType( + typeElement, + mirrors.toArray( new TypeMirror[] {} ) + ); + typeMirrorWithoutBounds = declaredType; + typeElementWithoutBounds = (TypeElement) declaredType.asElement(); + componentTypeWithoutBounds = null; + } + return new Type( typeUtils, elementUtils, typeFactory, accessorNaming, - declaredType, - (TypeElement) declaredType.asElement(), + typeMirrorWithoutBounds, + typeElementWithoutBounds, bounds, implementationType, - componentType, - builderType == null ? null : builderType.asBuilderInfo(), + componentTypeWithoutBounds, packageName, name, qualifiedName, @@ -442,28 +791,102 @@ public Type withoutBounds() { isCollectionType, isMapType, isStream, - isImported, - isLiteral + toBeImportedTypes, + notToBeImportedTypes, + isToBeImported, + isLiteral, + loggingVerbose ); } + private Type replaceGeneric(Type oldGenericType, Type newType) { + if ( !typeParameters.contains( oldGenericType ) || newType == null || oldGenericType.equals( newType ) ) { + return this; + } + newType = newType.getBoxedEquivalent(); + TypeMirror[] replacedTypeMirrors = new TypeMirror[typeParameters.size()]; + for ( int i = 0; i < typeParameters.size(); i++ ) { + Type typeParameter = typeParameters.get( i ); + replacedTypeMirrors[i] = + typeParameter.equals( oldGenericType ) ? newType.typeMirror : typeParameter.typeMirror; + } + + return typeFactory.getType( typeUtils.getDeclaredType( typeElement, replacedTypeMirrors ) ); + } + /** - * Whether this type is assignable to the given other type. + * Whether this type is assignable to the given other type, considering the "extends / upper bounds" + * as well. * * @param other The other type. * * @return {@code true} if and only if this type is assignable to the given other type. */ - // TODO This doesn't yet take super wild card types into account; - // e.g. Number wouldn't be assignable to ? super Number atm. (is there any practical use case) public boolean isAssignableTo(Type other) { + TypeMirror otherMirror = other.typeMirror; + if ( otherMirror.getKind() == TypeKind.WILDCARD ) { + otherMirror = typeUtils.erasure( other.typeMirror ); + } + if ( TypeKind.WILDCARD == typeMirror.getKind() ) { + return typeUtils.contains( typeMirror, otherMirror ); + } + return typeUtils.isAssignable( typeMirror, otherMirror ); + } + + /** + * Whether this type is raw assignable to the given other type. We can't make a verdict on typevars, + * they need to be resolved first. + * + * @param other The other type. + * + * @return {@code true} if and only if this type is assignable to the given other type. + */ + public boolean isRawAssignableTo(Type other) { + if ( isTypeVar() || other.isTypeVar() ) { + return true; + } if ( equals( other ) ) { return true; } + return typeUtils.isAssignable( typeUtils.erasure( typeMirror ), typeUtils.erasure( other.typeMirror ) ); + } - TypeMirror typeMirrorToMatch = isWildCardExtendsBound() ? getTypeBound().typeMirror : typeMirror; + /** + * removes any bounds from this type. + * @return the raw type + */ + public Type asRawType() { + if ( getTypeBound() != null ) { + return typeFactory.getType( typeUtils.erasure( typeMirror ) ); + } + else { + return this; + } + } + + public ReadAccessor getReadAccessor(String propertyName, boolean allowedMapToBean) { + if ( allowedMapToBean && hasStringMapSignature() ) { + ExecutableElement getMethod = getAllMethods() + .stream() + .filter( m -> m.getSimpleName().contentEquals( "get" ) ) + .filter( m -> m.getParameters().size() == 1 ) + .findAny() + .orElse( null ); + return new MapValueAccessor( getMethod, typeParameters.get( 1 ).getTypeMirror(), propertyName ); + } + + Map readAccessors = getPropertyReadAccessors(); - return typeUtils.isAssignable( typeMirrorToMatch, other.typeMirror ); + return readAccessors.get( propertyName ); + } + + public PresenceCheckAccessor getPresenceChecker(String propertyName) { + if ( hasStringMapSignature() ) { + return PresenceCheckAccessor.mapContainsKey( propertyName ); + } + + Map presenceCheckers = getPropertyPresenceCheckers(); + return presenceCheckers.get( propertyName ); } /** @@ -471,33 +894,49 @@ public boolean isAssignableTo(Type other) { * * @return an unmodifiable map of all read accessors (including 'is' for booleans), indexed by property name */ - public Map getPropertyReadAccessors() { + public Map getPropertyReadAccessors() { if ( readAccessors == null ) { - List getterList = Filters.getterMethodsIn( accessorNaming, getAllAccessors() ); - Map modifiableGetters = new LinkedHashMap(); - for ( Accessor getter : getterList ) { - String propertyName = accessorNaming.getPropertyName( getter ); + + Map recordAccessors = filters.recordAccessorsIn( getRecordComponents() ); + Map modifiableGetters = new LinkedHashMap<>(recordAccessors); + + List getterList = filters.getterMethodsIn( getAllMethods() ); + for ( ReadAccessor getter : getterList ) { + String simpleName = getter.getSimpleName(); + if ( recordAccessors.containsKey( simpleName ) ) { + // If there is already a record accessor that contains the simple name + // then it means that the getter is actually a record component. + // In that case we need to ignore it. + // e.g. record component named isActive. + // The DefaultAccessorNamingStrategy will return active as property name, + // but the property name is isActive, since it is a record + continue; + } + String propertyName = getPropertyName( getter ); + + if ( recordAccessors.containsKey( propertyName ) ) { + // If there is already a record accessor, the property needs to be ignored + continue; + } if ( modifiableGetters.containsKey( propertyName ) ) { // In the DefaultAccessorNamingStrategy, this can only be the case for Booleans: isFoo() and // getFoo(); The latter is preferred. - if ( !getter.getSimpleName().toString().startsWith( "is" ) ) { - modifiableGetters.put( accessorNaming.getPropertyName( getter ), getter ); + if ( !simpleName.startsWith( "is" ) ) { + modifiableGetters.put( propertyName, getter ); } } else { - modifiableGetters.put( accessorNaming.getPropertyName( getter ), getter ); + modifiableGetters.put( propertyName, getter ); } } - List fieldsList = Filters.fieldsIn( getAllAccessors() ); - for ( Accessor field : fieldsList ) { - String propertyName = accessorNaming.getPropertyName( field ); - if ( !modifiableGetters.containsKey( propertyName ) ) { - // If there was no getter or is method for booleans, then resort to the field. - // If a field was already added do not add it again. - modifiableGetters.put( propertyName, field ); - } + List fieldsList = filters.fieldsIn( getAllFields(), ReadAccessor::fromField ); + for ( ReadAccessor field : fieldsList ) { + String propertyName = getPropertyName( field ); + // If there was no getter or is method for booleans, then resort to the field. + // If a field was already added do not add it again. + modifiableGetters.putIfAbsent( propertyName, field ); } readAccessors = Collections.unmodifiableMap( modifiableGetters ); } @@ -509,16 +948,15 @@ public Map getPropertyReadAccessors() { * * @return an unmodifiable map of all presence checkers, indexed by property name */ - public Map getPropertyPresenceCheckers() { + public Map getPropertyPresenceCheckers() { if ( presenceCheckers == null ) { - List checkerList = Filters.presenceCheckMethodsIn( - accessorNaming, - getAllAccessors() - ); - Map modifiableCheckers = new LinkedHashMap(); - for ( ExecutableElementAccessor checker : checkerList ) { - modifiableCheckers.put( accessorNaming.getPropertyName( checker ), checker ); + List checkerList = filters.presenceCheckMethodsIn( getAllMethods() ); + Map modifiableCheckers = new LinkedHashMap<>(); + for ( ExecutableElement checker : checkerList ) { + modifiableCheckers.put( + getPropertyName( checker ), + PresenceCheckAccessor.methodInvocation( checker ) + ); } presenceCheckers = Collections.unmodifiableMap( modifiableCheckers ); } @@ -538,15 +976,19 @@ public Map getPropertyPresenceCheckers() { * @param cmStrategy collection mapping strategy * @return an unmodifiable map of all write accessors indexed by property name */ - public Map getPropertyWriteAccessors( CollectionMappingStrategyPrism cmStrategy ) { + public Map getPropertyWriteAccessors( CollectionMappingStrategyGem cmStrategy ) { + if ( isRecord() ) { + // Records do not have setters, so we return an empty map + return Collections.emptyMap(); + } // collect all candidate target accessors - List candidates = new ArrayList( getSetters() ); + List candidates = new ArrayList<>( getSetters() ); candidates.addAll( getAlternativeTargetAccessors() ); - Map result = new LinkedHashMap(); + Map result = new LinkedHashMap<>(); for ( Accessor candidate : candidates ) { - String targetPropertyName = accessorNaming.getPropertyName( candidate ); + String targetPropertyName = getPropertyName( candidate ); Accessor readAccessor = getPropertyReadAccessors().get( targetPropertyName ); @@ -556,18 +998,18 @@ public Map getPropertyWriteAccessors( CollectionMappingStrateg // A target access is in general a setter method on the target object. However, in case of collections, // the current target accessor can also be a getter method. // The following if block, checks if the target accessor should be overruled by an add method. - if ( cmStrategy == CollectionMappingStrategyPrism.SETTER_PREFERRED - || cmStrategy == CollectionMappingStrategyPrism.ADDER_PREFERRED - || cmStrategy == CollectionMappingStrategyPrism.TARGET_IMMUTABLE ) { + if ( cmStrategy == CollectionMappingStrategyGem.SETTER_PREFERRED + || cmStrategy == CollectionMappingStrategyGem.ADDER_PREFERRED + || cmStrategy == CollectionMappingStrategyGem.TARGET_IMMUTABLE ) { // first check if there's a setter method. Accessor adderMethod = null; - if ( accessorNaming.isSetterMethod( candidate ) + if ( candidate.getAccessorType() == AccessorType.SETTER // ok, the current accessor is a setter. So now the strategy determines what to use - && cmStrategy == CollectionMappingStrategyPrism.ADDER_PREFERRED ) { + && cmStrategy == CollectionMappingStrategyGem.ADDER_PREFERRED ) { adderMethod = getAdderForType( targetType, targetPropertyName ); } - else if ( accessorNaming.isGetterMethod( candidate ) ) { + else if ( candidate.getAccessorType() == AccessorType.GETTER ) { // the current accessor is a getter (no setter available). But still, an add method is according // to the above strategy (SETTER_PREFERRED || ADDER_PREFERRED) preferred over the getter. adderMethod = getAdderForType( targetType, targetPropertyName ); @@ -576,13 +1018,24 @@ else if ( accessorNaming.isGetterMethod( candidate ) ) { // an adder has been found (according strategy) so overrule current choice. candidate = adderMethod; } + } - else if ( Executables.isFieldAccessor( candidate ) && ( Executables.isFinal( candidate ) || + else if ( candidate.getAccessorType() == AccessorType.FIELD && ( Executables.isFinal( candidate ) || result.containsKey( targetPropertyName ) ) ) { // if the candidate is a field and a mapping already exists, then use that one, skip it. continue; } + if ( candidate.getAccessorType() == AccessorType.GETTER ) { + // When the candidate is a getter then it can't be used in the following cases: + // 1. The collection mapping strategy is target immutable + // 2. The target type is a stream (streams are immutable) + if ( cmStrategy == CollectionMappingStrategyGem.TARGET_IMMUTABLE || + targetType != null && targetType.isStreamType() ) { + continue; + } + } + Accessor previousCandidate = result.get( targetPropertyName ); if ( previousCandidate == null || preferredType == null || ( targetType != null && typeUtils.isAssignable( preferredType.getTypeMirror(), targetType.getTypeMirror() ) ) ) { @@ -593,6 +1046,14 @@ else if ( Executables.isFieldAccessor( candidate ) && ( Executables.isFinal( can return result; } + public List getRecordComponents() { + if ( recordComponents == null ) { + recordComponents = nullSafeTypeElementListConversion( filters::recordComponentsIn ); + } + + return recordComponents; + } + private Type determinePreferredType(Accessor readAccessor) { if ( readAccessor != null ) { return typeFactory.getReturnType( (DeclaredType) typeMirror, readAccessor ); @@ -605,18 +1066,49 @@ private Type determineTargetType(Accessor candidate) { if ( parameter != null ) { return parameter.getType(); } - else if ( accessorNaming.isGetterMethod( candidate ) || Executables.isFieldAccessor( candidate ) ) { + else if ( candidate.getAccessorType() == AccessorType.GETTER + || candidate.getAccessorType().isFieldAssignment() ) { return typeFactory.getReturnType( (DeclaredType) typeMirror, candidate ); } return null; } - private List getAllAccessors() { - if ( allAccessors == null ) { - allAccessors = Executables.getAllEnclosedAccessors( elementUtils, typeElement ); + private List getAllMethods() { + if ( allMethods == null ) { + allMethods = nullSafeTypeElementListConversion( elementUtils::getAllEnclosedExecutableElements ); } - return allAccessors; + return allMethods; + } + + private List getAllFields() { + if ( allFields == null ) { + allFields = nullSafeTypeElementListConversion( elementUtils::getAllEnclosedFields ); + } + + return allFields; + } + + private List nullSafeTypeElementListConversion(Function> conversionFunction) { + if ( typeElement != null ) { + return conversionFunction.apply( typeElement ); + } + + return Collections.emptyList(); + } + + private String getPropertyName(Accessor accessor ) { + Element accessorElement = accessor.getElement(); + if ( accessorElement instanceof ExecutableElement ) { + return getPropertyName( (ExecutableElement) accessorElement ); + } + else { + return accessor.getSimpleName(); + } + } + + private String getPropertyName(ExecutableElement element) { + return accessorNaming.getPropertyName( element ); } /** @@ -638,54 +1130,78 @@ private List getAllAccessors() { */ private Accessor getAdderForType(Type collectionProperty, String pluralPropertyName) { - List candidates = new ArrayList(); - if ( collectionProperty.isCollectionType ) { - - // this is a collection, so this can be done always - TypeMirror typeArg = first( collectionProperty.determineTypeArguments( Iterable.class ) ).getTypeBound() - .getTypeMirror(); - // now, look for a method that - // 1) starts with add, - // 2) and has typeArg as one and only arg - List adderList = getAdders(); - for ( Accessor adder : adderList ) { - ExecutableElement executable = adder.getExecutable(); - if ( executable == null ) { - // it should not be null, but to be safe - continue; - } - VariableElement arg = executable.getParameters().get( 0 ); - if ( typeUtils.isSameType( arg.asType(), typeArg ) ) { - candidates.add( adder ); - } - } + List candidates; + + if ( collectionProperty.isCollectionType() ) { + candidates = getAccessorCandidates( collectionProperty, Iterable.class ); + } + else if ( collectionProperty.isStreamType() ) { + candidates = getAccessorCandidates( collectionProperty, Stream.class ); + } + else { + return null; } + if ( candidates.isEmpty() ) { return null; } - else if ( candidates.size() == 1 ) { + + if ( candidates.size() == 1 ) { return candidates.get( 0 ); } - else { - for ( Accessor candidate : candidates ) { - String elementName = accessorNaming.getElementNameForAdder( candidate ); - if ( elementName != null && elementName.equals( Nouns.singularize( pluralPropertyName ) ) ) { - return candidate; - } + + for ( Accessor candidate : candidates ) { + String elementName = accessorNaming.getElementNameForAdder( candidate ); + if ( elementName != null && elementName.equals( Nouns.singularize( pluralPropertyName ) ) ) { + return candidate; } } return null; } + /** + * Returns all accessor candidates that start with "add" and have exactly one argument + * whose type matches the collection or stream property's type argument. + * + * @param property the collection or stream property + * @param superclass the superclass to use for type argument lookup + * + * @return accessor candidates + */ + private List getAccessorCandidates(Type property, Class superclass) { + TypeMirror typeArg = first( property.determineTypeArguments( superclass ) ).getTypeBound().getTypeMirror(); + // now, look for a method that + // 1) starts with add, + // 2) and has typeArg as one and only arg + List adderList = getAdders(); + List candidateList = new ArrayList<>(); + for ( Accessor adder : adderList ) { + TypeMirror adderParameterType = determineTargetType( adder ).getTypeMirror(); + if ( typeUtils.isSameType( boxed( adderParameterType ), boxed( typeArg ) ) ) { + candidateList.add( adder ); + } + } + return candidateList; + } + + private TypeMirror boxed(TypeMirror possiblePrimitive) { + if ( possiblePrimitive.getKind().isPrimitive() ) { + return typeUtils.boxedClass( (PrimitiveType) possiblePrimitive ).asType(); + } + else { + return possiblePrimitive; + } + } + /** * getSetters * * @return an unmodifiable list of all setters */ - private List getSetters() { + public List getSetters() { if ( setters == null ) { - setters = Collections.unmodifiableList( Filters.setterMethodsIn( accessorNaming, getAllAccessors() ) ); + setters = Collections.unmodifiableList( filters.setterMethodsIn( getAllMethods() ) ); } return setters; } @@ -700,7 +1216,7 @@ private List getSetters() { */ private List getAdders() { if ( adders == null ) { - adders = Collections.unmodifiableList( Filters.adderMethodsIn( accessorNaming, getAllAccessors() ) ); + adders = Collections.unmodifiableList( filters.adderMethodsIn( getAllMethods() ) ); } return adders; } @@ -715,25 +1231,31 @@ private List getAdders() { * @return an unmodifiable list of alternative target accessors. */ private List getAlternativeTargetAccessors() { + if ( alternativeTargetAccessors != null ) { + return alternativeTargetAccessors; + } + + if ( isRecord() ) { + alternativeTargetAccessors = Collections.emptyList(); + } if ( alternativeTargetAccessors == null ) { - List result = new ArrayList(); + List result = new ArrayList<>(); List setterMethods = getSetters(); - List readAccessors = - new ArrayList( getPropertyReadAccessors().values() ); + List readAccessors = new ArrayList<>( getPropertyReadAccessors().values() ); // All the fields are also alternative accessors - readAccessors.addAll( Filters.fieldsIn( getAllAccessors() ) ); + readAccessors.addAll( filters.fieldsIn( getAllFields(), ElementAccessor::new ) ); // there could be a read accessor (field or method) for a list/map that is not present as setter. // an accessor could substitute the setter in that case and act as setter. // (assuming it is initialized) for ( Accessor readAccessor : readAccessors ) { - if ( isCollectionOrMap( readAccessor ) && + if ( isCollectionOrMapOrStream( readAccessor ) && !correspondingSetterMethodExists( readAccessor, setterMethods ) ) { result.add( readAccessor ); } - else if ( Executables.isFieldAccessor( readAccessor ) && + else if ( readAccessor.getAccessorType() == AccessorType.FIELD && !correspondingSetterMethodExists( readAccessor, setterMethods ) ) { result.add( readAccessor ); } @@ -746,10 +1268,10 @@ else if ( Executables.isFieldAccessor( readAccessor ) && private boolean correspondingSetterMethodExists(Accessor getterMethod, List setterMethods) { - String getterPropertyName = accessorNaming.getPropertyName( getterMethod ); + String getterPropertyName = getPropertyName( getterMethod ); for ( Accessor setterMethod : setterMethods ) { - String setterPropertyName = accessorNaming.getPropertyName( setterMethod ); + String setterPropertyName = getPropertyName( setterMethod ); if ( getterPropertyName.equals( setterPropertyName ) ) { return true; } @@ -758,14 +1280,21 @@ private boolean correspondingSetterMethodExists(Accessor getterMethod, return false; } - private boolean isCollectionOrMap(Accessor getterMethod) { - return isCollection( getterMethod.getAccessedType() ) || isMap( getterMethod.getAccessedType() ); + private boolean isCollectionOrMapOrStream(Accessor getterMethod) { + return isCollection( getterMethod.getAccessedType() ) || isMap( getterMethod.getAccessedType() ) || + isStream( getterMethod.getAccessedType() ); } private boolean isCollection(TypeMirror candidate) { return isSubType( candidate, Collection.class ); } + private boolean isStream(TypeMirror candidate) { + TypeElement streamTypeElement = elementUtils.getTypeElement( JavaStreamConstants.STREAM_FQN ); + TypeMirror streamType = streamTypeElement == null ? null : typeUtils.erasure( streamTypeElement.asType() ); + return streamType != null && typeUtils.isSubtypeErased( candidate, streamType ); + } + private boolean isMap(TypeMirror candidate) { return isSubType( candidate, Map.class ); } @@ -773,7 +1302,7 @@ private boolean isMap(TypeMirror candidate) { private boolean isSubType(TypeMirror candidate, Class clazz) { String className = clazz.getCanonicalName(); TypeMirror classType = typeUtils.erasure( elementUtils.getTypeElement( className ).asType() ); - return typeUtils.isSubtype( candidate, classType ); + return typeUtils.isSubtypeErased( candidate, classType ); } /** @@ -835,6 +1364,10 @@ else if ( !method.getModifiers().contains( Modifier.PUBLIC ) ) { * FTL. */ public String getNull() { + if ( isOptionalType() ) { + return createReferenceName() + ".empty()"; + } + if ( !isPrimitive() || isArrayType() ) { return "null"; } @@ -866,6 +1399,22 @@ public String getNull() { throw new UnsupportedOperationException( getName() ); } + public String getSensibleDefault() { + if ( isPrimitive() ) { + return getNull(); + } + else if ( "String".equals( getName() ) ) { + return "\"\""; + } + else { + if ( isNative() ) { + // must be boxed, since primitive is already checked + return typeFactory.getType( typeUtils.unboxedType( typeMirror ) ).getNull(); + } + } + return null; + } + @Override public int hashCode() { // javadoc typemirror: "Types should be compared using the utility methods in Types. There is no guarantee @@ -891,7 +1440,14 @@ public boolean equals(Object obj) { } Type other = (Type) obj; - return typeUtils.isSameType( typeMirror, other.typeMirror ); + if ( this.isWildCardBoundByTypeVar() && other.isWildCardBoundByTypeVar() ) { + return ( this.hasExtendsBound() == other.hasExtendsBound() + || this.hasSuperBound() == other.hasSuperBound() ) + && typeUtils.isSameType( getTypeBound().getTypeMirror(), other.getTypeBound().getTypeMirror() ); + } + else { + return typeUtils.isSameType( typeMirror, other.typeMirror ); + } } @Override @@ -904,6 +1460,36 @@ public String toString() { return typeMirror.toString(); } + /** + * @return a string representation of the type for use in messages + */ + public String describe() { + if ( loggingVerbose ) { + return toString(); + } + else { + // name allows for inner classes + String name = getNameKeepingInnerClasses(); + List typeParams = getTypeParameters(); + if ( typeParams.isEmpty() ) { + return name; + } + else { + String params = typeParams.stream().map( Type::describe ).collect( Collectors.joining( "," ) ); + return String.format( "%s<%s>", name, params ); + } + } + } + + private String getNameKeepingInnerClasses() { + String packageNamePrefix = getPackageName() + "."; + String fullyQualifiedName = getFullyQualifiedName(); + if ( fullyQualifiedName.startsWith( packageNamePrefix ) ) { + return fullyQualifiedName.substring( packageNamePrefix.length() ); + } + return fullyQualifiedName; + } + /** * * @return an identification that can be used as part in a forged method name. @@ -937,20 +1523,95 @@ public Type getTypeBound() { return boundingBase; } - public boolean hasEmptyAccessibleContructor() { + public List getTypeBounds() { + if ( this.boundTypes != null ) { + return boundTypes; + } + Type bound = getTypeBound(); + if ( bound == null ) { + this.boundTypes = Collections.emptyList(); + } + else if ( !bound.isIntersection() ) { + this.boundTypes = Collections.singletonList( bound ); + } + else { + List bounds = ( (IntersectionType) bound.typeMirror ).getBounds(); + this.boundTypes = new ArrayList<>( bounds.size() ); + for ( TypeMirror mirror : bounds ) { + boundTypes.add( typeFactory.getType( mirror ) ); + } + } + + return this.boundTypes; + + } - if ( this.hasEmptyAccessibleContructor == null ) { - hasEmptyAccessibleContructor = false; + public boolean hasAccessibleConstructor() { + if ( hasAccessibleConstructor == null ) { + hasAccessibleConstructor = false; List constructors = ElementFilter.constructorsIn( typeElement.getEnclosedElements() ); for ( ExecutableElement constructor : constructors ) { - if ( !constructor.getModifiers().contains( Modifier.PRIVATE ) - && constructor.getParameters().isEmpty() ) { - hasEmptyAccessibleContructor = true; + if ( !constructor.getModifiers().contains( Modifier.PRIVATE ) ) { + hasAccessibleConstructor = true; break; } } } - return hasEmptyAccessibleContructor; + return hasAccessibleConstructor; + } + + /** + * Whether this type can be instantiated through an accessible parameterless constructor, i.e. via + * {@code new Type()}. Unlike {@link #hasAccessibleConstructor()} this returns {@code false} for types that + * only expose constructors with parameters (e.g. {@code BigDecimal}). + * + * @return {@code true} if a {@code new Type()} call would compile, {@code false} otherwise + */ + public boolean hasAccessibleParameterlessConstructor() { + if ( typeElement == null || isInterface() || isAbstract() || isEnumType() ) { + return false; + } + List constructors = ElementFilter.constructorsIn( typeElement.getEnclosedElements() ); + if ( constructors.isEmpty() ) { + // no declared constructors means the implicit, accessible default constructor is available + return true; + } + for ( ExecutableElement constructor : constructors ) { + if ( !constructor.getModifiers().contains( Modifier.PRIVATE ) && constructor.getParameters().isEmpty() ) { + return true; + } + } + return false; + } + + public KotlinMetadata getKotlinMetadata() { + if ( !kotlinMetadataInitialized ) { + kotlinMetadataInitialized = true; + if ( typeElement != null && KOTLIN_METADATA_JVM_PRESENT ) { + Metadata metadataAnnotation = typeElement.getAnnotation( Metadata.class ); + if ( metadataAnnotation != null ) { + KotlinClassMetadata classMetadata = KotlinClassMetadata.readLenient( metadataAnnotation ); + if ( classMetadata instanceof KotlinClassMetadata.Class ) { + kotlinMetadata = new KotlinMetadataImpl( (KotlinClassMetadata.Class) classMetadata ); + } + } + } + } + + return kotlinMetadata; + } + + /** + * Returns the direct supertypes of a type. The interface types, if any, + * will appear last in the list. + * + * @return the direct supertypes, or an empty list if none + */ + public List getDirectSuperTypes() { + return typeUtils.directSupertypes( typeMirror ) + .stream() + .map( typeFactory::getType ) + .collect( Collectors.toList() ); } /** @@ -988,4 +1649,567 @@ public boolean isLiteral() { return isLiteral; } + /** + * Steps through the declaredType in order to find a match for this typeVar Type. It aligns with + * the provided parameterized type where this typeVar type is used.
    + *
    + * For example:

    +     * {@code
    +     * this: T
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: String
    +     *
    +     *
    +     * this: T, T[] or ? extends T,
    +     * declaredType: E.g. Callable
    +     * parameterizedType: Callable
    +     * return: BigDecimal
    +     * }
    +     * 
    + * + * @param declared the type + * @param parameterized the parameterized type + * + * @return - the same type when this is not a type var in the broadest sense (T, T[], or ? extends T)
    + * - the matching parameter in the parameterized type when this is a type var when found
    + * - null in all other cases + */ + public ResolvedPair resolveParameterToType(Type declared, Type parameterized) { + if ( isTypeVar() || isArrayTypeVar() || isWildCardBoundByTypeVar() ) { + TypeVarMatcher typeVarMatcher = new TypeVarMatcher( typeFactory, typeUtils, this ); + return typeVarMatcher.visit( parameterized.getTypeMirror(), declared ); + } + return new ResolvedPair( this, this ); + } + + /** + * Resolves generic types using the declared and parameterized types as input.
    + *
    + * For example: + *
    +     * {@code
    +     * this: T
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: Integer
    +     *
    +     * this: List
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: List
    +     *
    +     * this: List
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: List
    +     *
    +     * this: List>
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: List>
    +     * }
    +     * 
    + * It also works for partial matching.
    + *
    + * For example: + *
    +     * {@code
    +     * this: Map
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: Map
    +     * }
    +     * 
    + * It also works with multiple parameters at both sides.
    + *
    + * For example when reversing Key/Value for a Map: + *
    +     * {@code
    +     * this: Map
    +     * declaredType: HashMap
    +     * parameterizedType: HashMap
    +     * result: Map
    +     * }
    +     * 
    + * + * Mismatch result examples: + *
    +     * {@code
    +     * this: T
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: null
    +     *
    +     * this: List
    +     * declaredType: JAXBElement
    +     * parameterizedType: JAXBElement
    +     * result: List
    +     * }
    +     * 
    + * + * @param declared the type + * @param parameterized the parameterized type + * + * @return - the result of {@link #resolveParameterToType(Type, Type)} when this type itself is a type var.
    + * - the type but then with the matching type parameters replaced.
    + * - the same type when this type does not contain matching type parameters. + */ + public Type resolveGenericTypeParameters(Type declared, Type parameterized) { + if ( isTypeVar() || isArrayTypeVar() || isWildCardBoundByTypeVar() ) { + return resolveParameterToType( declared, parameterized ).getMatch(); + } + Type resultType = this; + for ( Type generic : getTypeParameters() ) { + if ( generic.isTypeVar() || generic.isArrayTypeVar() || generic.isWildCardBoundByTypeVar() ) { + ResolvedPair resolveParameterToType = generic.resolveParameterToType( declared, parameterized ); + resultType = resultType.replaceGeneric( generic, resolveParameterToType.getMatch() ); + } + else { + Type replacementType = generic.resolveParameterToType( declared, parameterized ).getMatch(); + resultType = resultType.replaceGeneric( generic, replacementType ); + } + } + return resultType; + } + + public boolean isWildCardBoundByTypeVar() { + return ( hasExtendsBound() || hasSuperBound() ) && getTypeBound().isTypeVar(); + } + + public boolean isArrayTypeVar() { + return isArrayType() && getComponentType().isTypeVar(); + } + + private static class TypeVarMatcher extends SimpleTypeVisitor8 { + + private final TypeFactory typeFactory; + private final Type typeToMatch; + private final TypeUtils types; + + /** + * @param typeFactory factory + * @param types type utils + * @param typeToMatch the typeVar or wildcard with typeVar bound + */ + TypeVarMatcher(TypeFactory typeFactory, TypeUtils types, Type typeToMatch) { + super( new ResolvedPair( typeToMatch, null ) ); + this.typeFactory = typeFactory; + this.typeToMatch = typeToMatch; + this.types = types; + } + + @Override + public ResolvedPair visitTypeVariable(TypeVariable parameterized, Type declared) { + if ( typeToMatch.isTypeVar() && types.isSameType( parameterized, typeToMatch.getTypeMirror() ) ) { + return new ResolvedPair( typeFactory.getType( parameterized ), declared ); + } + return super.DEFAULT_VALUE; + } + + /** + * If ? extends SomeTime equals the boundary set in typeVarToMatch (NOTE: you can't compare the wildcard itself) + * then return a result; + */ + @Override + public ResolvedPair visitWildcard(WildcardType parameterized, Type declared) { + if ( typeToMatch.hasExtendsBound() && parameterized.getExtendsBound() != null + && types.isSameType( typeToMatch.getTypeBound().getTypeMirror(), parameterized.getExtendsBound() ) ) { + return new ResolvedPair( typeToMatch, declared); + } + else if ( typeToMatch.hasSuperBound() && parameterized.getSuperBound() != null + && types.isSameType( typeToMatch.getTypeBound().getTypeMirror(), parameterized.getSuperBound() ) ) { + return new ResolvedPair( typeToMatch, declared); + } + if ( parameterized.getExtendsBound() != null ) { + ResolvedPair match = visit( parameterized.getExtendsBound(), declared ); + if ( match.match != null ) { + return new ResolvedPair( typeFactory.getType( parameterized ), declared ); + } + } + else if ( parameterized.getSuperBound() != null ) { + ResolvedPair match = visit( parameterized.getSuperBound(), declared ); + if ( match.match != null ) { + return new ResolvedPair( typeFactory.getType( parameterized ), declared ); + } + + } + return super.DEFAULT_VALUE; + } + + @Override + public ResolvedPair visitArray(ArrayType parameterized, Type declared) { + if ( types.isSameType( parameterized.getComponentType(), typeToMatch.getTypeMirror() ) ) { + return new ResolvedPair( typeFactory.getType( parameterized ), declared ); + } + if ( declared.isArrayType() ) { + return visit( parameterized.getComponentType(), declared.getComponentType() ); + } + return super.DEFAULT_VALUE; + } + + @Override + public ResolvedPair visitDeclared(DeclaredType parameterized, Type declared) { + + List results = new ArrayList<>( ); + if ( parameterized.getTypeArguments().isEmpty() ) { + return super.DEFAULT_VALUE; + } + else if ( types.isSameType( types.erasure( parameterized ), types.erasure( declared.getTypeMirror() ) ) ) { + // We can't assume that the type args are the same + // e.g. List is assignable to Object + if ( parameterized.getTypeArguments().size() != declared.getTypeParameters().size() ) { + return super.visitDeclared( parameterized, declared ); + } + + // only possible to compare parameters when the types are exactly the same + for ( int i = 0; i < parameterized.getTypeArguments().size(); i++ ) { + TypeMirror parameterizedTypeArg = parameterized.getTypeArguments().get( i ); + Type declaredTypeArg = declared.getTypeParameters().get( i ); + if ( parameterizedTypeArg.getKind() == TypeKind.DECLARED && + !types.isSameType( types.erasure( parameterizedTypeArg ), + types.erasure( declaredTypeArg.getTypeMirror() ) ) ) { + // Comparable can never be assigned Comparable + // Generics enforce exact matches for declared types + return DEFAULT_VALUE; + } + ResolvedPair result = visit( parameterizedTypeArg, declaredTypeArg ); + if ( result != super.DEFAULT_VALUE ) { + results.add( result ); + } + } + } + else { + // Also check whether the implemented interfaces are parameterized + for ( Type declaredSuperType : declared.getDirectSuperTypes() ) { + if ( Object.class.getName().equals( declaredSuperType.getFullyQualifiedName() ) ) { + continue; + } + ResolvedPair result = visitDeclared( parameterized, declaredSuperType ); + if ( result != super.DEFAULT_VALUE ) { + results.add( result ); + } + } + + for ( TypeMirror parameterizedSuper : types.directSupertypes( parameterized ) ) { + if ( isJavaLangObject( parameterizedSuper ) ) { + continue; + } + ResolvedPair result = visitDeclared( (DeclaredType) parameterizedSuper, declared ); + if ( result != super.DEFAULT_VALUE ) { + results.add( result ); + } + } + } + if ( results.isEmpty() ) { + return super.DEFAULT_VALUE; + } + else { + return results.stream().allMatch( results.get( 0 )::equals ) ? results.get( 0 ) : super.DEFAULT_VALUE; + } + } + + private boolean isJavaLangObject(TypeMirror type) { + if ( type instanceof DeclaredType ) { + return ( (TypeElement) ( (DeclaredType) type ).asElement() ).getQualifiedName() + .contentEquals( Object.class.getName() ); + } + return false; + } + } + + /** + * Reflects any Resolved Pair, examples are + * T, String + * ? extends T, BigDecimal + * T[], Integer[] + */ + public static class ResolvedPair { + + public ResolvedPair(Type parameter, Type match) { + this.parameter = parameter; + this.match = match; + } + + /** + * parameter, e.g. T, ? extends T or T[] + */ + private Type parameter; + + /** + * match, e.g. String, BigDecimal, Integer[] + */ + private Type match; + + public Type getParameter() { + return parameter; + } + + public Type getMatch() { + return match; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + ResolvedPair that = (ResolvedPair) o; + return Objects.equals( parameter, that.parameter ) && Objects.equals( match, that.match ); + } + + @Override + public int hashCode() { + return Objects.hash( parameter ); + } + } + + /** + * Gets the boxed equivalent type if the type is primitive, int will return Integer + * + * @return boxed equivalent + */ + public Type getBoxedEquivalent() { + if ( boxedEquivalent != null ) { + return boxedEquivalent; + } + else if ( isPrimitive() ) { + boxedEquivalent = typeFactory.getType( typeUtils.boxedClass( (PrimitiveType) typeMirror ) ); + return boxedEquivalent; + } + return this; + } + + /** + * It strips all the {@code []} from the {@code className}. + * + * E.g. + *
    +     *     trimSimpleClassName("String[][][]") -> "String"
    +     *     trimSimpleClassName("String[]") -> "String"
    +     * 
    + * + * @param className that needs to be trimmed + * + * @return the trimmed {@code className}, or {@code null} if the {@code className} was {@code null} + */ + private String trimSimpleClassName(String className) { + if ( className == null ) { + return null; + } + String trimmedClassName = className; + while ( trimmedClassName.endsWith( "[]" ) ) { + trimmedClassName = trimmedClassName.substring( 0, trimmedClassName.length() - 2 ); + } + return trimmedClassName; + } + + private static String nameWithTopLevelTypeName(TypeElement element, String name) { + if ( element == null ) { + return null; + } + if ( !element.getNestingKind().isNested() ) { + return name; + } + + Deque elements = new ArrayDeque<>(); + elements.addFirst( name ); + Element parent = element.getEnclosingElement(); + while ( parent != null && parent.getKind() != ElementKind.PACKAGE ) { + elements.addFirst( parent.getSimpleName() ); + parent = parent.getEnclosingElement(); + } + + return String.join( ".", elements ); + } + + private static Type topLevelType(TypeElement typeElement, TypeFactory typeFactory) { + if ( typeElement == null || typeElement.getNestingKind() == NestingKind.TOP_LEVEL ) { + return null; + } + + Element parent = typeElement.getEnclosingElement(); + while ( parent != null ) { + if ( parent.getEnclosingElement() != null && + parent.getEnclosingElement().getKind() == ElementKind.PACKAGE ) { + break; + } + parent = parent.getEnclosingElement(); + } + return parent == null ? null : typeFactory.getType( parent.asType() ); + } + + public boolean isEnumSet() { + return "java.util.EnumSet".equals( getFullyQualifiedName() ); + } + + /** + * return true if this type is a java 17+ sealed class + */ + public boolean isSealed() { + KotlinMetadata kotlinMetadata = getKotlinMetadata(); + if ( kotlinMetadata != null ) { + return kotlinMetadata.isSealedClass(); + } + return typeElement.getModifiers().stream().map( Modifier::name ).anyMatch( "SEALED"::equals ); + } + + /** + * return the list of permitted TypeMirrors for the java 17+ sealed class + */ + @SuppressWarnings( "unchecked" ) + public List getPermittedSubclasses() { + KotlinMetadata kotlinMetadata = getKotlinMetadata(); + if ( kotlinMetadata != null ) { + return kotlinMetadata.getPermittedSubclasses(); + } + if ( SEALED_PERMITTED_SUBCLASSES_METHOD == null ) { + return emptyList(); + } + try { + return (List) SEALED_PERMITTED_SUBCLASSES_METHOD.invoke( typeElement ); + } + catch ( IllegalAccessException | IllegalArgumentException | InvocationTargetException e ) { + return emptyList(); + } + } + + private class KotlinMetadataImpl implements KotlinMetadata { + + private final KotlinClassMetadata.Class kotlinClassMetadata; + + private KotlinMetadataImpl(KotlinClassMetadata.Class kotlinClassMetadata) { + this.kotlinClassMetadata = kotlinClassMetadata; + } + + @Override + public boolean isDataClass() { + return Attributes.isData( kotlinClassMetadata.getKmClass() ); + } + + @Override + public boolean isSealedClass() { + return Attributes.getModality( kotlinClassMetadata.getKmClass() ) == Modality.SEALED; + } + + @Override + public ExecutableElement determinePrimaryConstructor(List constructors) { + if ( constructors.size() == 1 ) { + // If we have one constructor, that this constructor is the primary one + return constructors.get( 0 ); + } + KmClass kmClass = kotlinClassMetadata.getKmClass(); + KmConstructor primaryKmConstructor = null; + for ( KmConstructor constructor : kmClass.getConstructors() ) { + if ( !Attributes.isSecondary( constructor ) ) { + primaryKmConstructor = constructor; + } + + } + + if ( primaryKmConstructor == null ) { + return null; + } + + List sameParametersSizeConstructors = new ArrayList<>(); + for ( ExecutableElement constructor : constructors ) { + if ( constructor.getParameters().size() == primaryKmConstructor.getValueParameters().size() ) { + sameParametersSizeConstructors.add( constructor ); + } + } + + if ( sameParametersSizeConstructors.size() == 1 ) { + return sameParametersSizeConstructors.get( 0 ); + } + + JvmMethodSignature signature = JvmExtensionsKt.getSignature( primaryKmConstructor ); + if ( signature == null ) { + return null; + } + + String signatureDescriptor = signature.getDescriptor(); + for ( ExecutableElement constructor : constructors ) { + String constructorDescriptor = buildJvmConstructorDescriptor( constructor ); + if ( signatureDescriptor.equals( constructorDescriptor ) ) { + return constructor; + } + } + + return null; + } + + @Override + public List getPermittedSubclasses() { + List sealedSubclassNames = kotlinClassMetadata.getKmClass().getSealedSubclasses(); + List permittedSubclasses = new ArrayList<>( sealedSubclassNames.size() ); + for ( String sealedSubclassName : sealedSubclassNames ) { + Type subclassType = typeFactory.getType( sealedSubclassName.replace( '/', '.' ) ); + permittedSubclasses.add( subclassType.getTypeMirror() ); + } + + return permittedSubclasses; + } + + private String buildJvmConstructorDescriptor(ExecutableElement constructor) { + StringBuilder signature = new StringBuilder( "(" ); + + for ( VariableElement param : constructor.getParameters() ) { + signature.append( getJvmTypeDescriptor( param.asType() ) ); + } + + signature.append( ")V" ); + return signature.toString(); + } + + private String getJvmTypeDescriptor(TypeMirror type) { + return type.accept( + new SimpleTypeVisitor8() { + @Override + public String visitPrimitive(PrimitiveType t, Void p) { + switch ( t.getKind() ) { + case BOOLEAN: + return "Z"; + case BYTE: + return "B"; + case SHORT: + return "S"; + case INT: + return "I"; + case LONG: + return "J"; + case CHAR: + return "C"; + case FLOAT: + return "F"; + case DOUBLE: + return "D"; + default: + return ""; + } + } + + @Override + public String visitDeclared(DeclaredType t, Void p) { + TypeElement element = (TypeElement) t.asElement(); + String binaryName = elementUtils.getBinaryName( element ).toString(); + return "L" + binaryName.replace( '.', '/' ) + ";"; + } + + @Override + public String visitArray(ArrayType t, Void p) { + return "[" + getJvmTypeDescriptor( t.getComponentType() ); + } + + @Override + protected String defaultAction(TypeMirror e, Void p) { + return ""; + } + }, null + ); + } + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java index 13e38cc5c8..8d79780d35 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/TypeFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; @@ -23,6 +10,8 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.NavigableMap; @@ -36,7 +25,6 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentNavigableMap; import java.util.concurrent.ConcurrentSkipListMap; - import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; @@ -50,24 +38,29 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; import javax.lang.model.type.WildcardType; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.gem.BuilderGem; import org.mapstruct.ap.internal.util.AnnotationProcessingException; import org.mapstruct.ap.internal.util.Collections; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.Extractor; import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.JavaCollectionConstants; import org.mapstruct.ap.internal.util.JavaStreamConstants; import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.NativeTypes; import org.mapstruct.ap.internal.util.RoundContext; import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.util.accessor.Accessor; +import org.mapstruct.ap.internal.version.VersionInformation; import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; import org.mapstruct.ap.spi.BuilderInfo; import org.mapstruct.ap.spi.MoreThanOneBuilderCreationMethodException; import org.mapstruct.ap.spi.TypeHierarchyErroneousException; import static org.mapstruct.ap.internal.model.common.ImplementationType.withDefaultConstructor; +import static org.mapstruct.ap.internal.model.common.ImplementationType.withFactoryMethod; import static org.mapstruct.ap.internal.model.common.ImplementationType.withInitialCapacity; import static org.mapstruct.ap.internal.model.common.ImplementationType.withLoadFactorAdjustment; @@ -79,15 +72,24 @@ public class TypeFactory { private static final Extractor BUILDER_INFO_CREATION_METHOD_EXTRACTOR = - new Extractor() { - @Override - public String apply(BuilderInfo builderInfo) { - return builderInfo.getBuilderCreationMethod().toString(); + builderInfo -> { + ExecutableElement builderCreationMethod = builderInfo.getBuilderCreationMethod(); + + StringBuilder sb = new StringBuilder( builderCreationMethod.getSimpleName() ); + + sb.append( '(' ); + for ( VariableElement parameter : builderCreationMethod.getParameters() ) { + sb.append( parameter ); } + + sb.append( ')' ); + return sb.toString(); }; + private static final String LINKED_HASH_SET_FACTORY_METHOD_NAME = "newLinkedHashSet"; + private static final String LINKED_HASH_MAP_FACTORY_METHOD_NAME = "newLinkedHashMap"; - private final Elements elementUtils; - private final Types typeUtils; + private final ElementUtils elementUtils; + private final TypeUtils typeUtils; private final FormattingMessager messager; private final RoundContext roundContext; @@ -96,14 +98,20 @@ public String apply(BuilderInfo builderInfo) { private final TypeMirror mapType; private final TypeMirror streamType; - private final Map implementationTypes = new HashMap(); - private final Map importedQualifiedTypesBySimpleName = new HashMap(); + private final Map implementationTypes = new HashMap<>(); + private final Map toBeImportedTypes = new HashMap<>(); + private final Map notToBeImportedTypes; + + private final boolean loggingVerbose; - public TypeFactory(Elements elementUtils, Types typeUtils, FormattingMessager messager, RoundContext roundContext) { + public TypeFactory(ElementUtils elementUtils, TypeUtils typeUtils, FormattingMessager messager, + RoundContext roundContext, Map notToBeImportedTypes, boolean loggingVerbose, + VersionInformation versionInformation) { this.elementUtils = elementUtils; this.typeUtils = typeUtils; this.messager = messager; this.roundContext = roundContext; + this.notToBeImportedTypes = notToBeImportedTypes; iterableType = typeUtils.erasure( elementUtils.getTypeElement( Iterable.class.getCanonicalName() ).asType() ); collectionType = @@ -116,11 +124,22 @@ public TypeFactory(Elements elementUtils, Types typeUtils, FormattingMessager me implementationTypes.put( Collection.class.getName(), withInitialCapacity( getType( ArrayList.class ) ) ); implementationTypes.put( List.class.getName(), withInitialCapacity( getType( ArrayList.class ) ) ); - implementationTypes.put( Set.class.getName(), withLoadFactorAdjustment( getType( HashSet.class ) ) ); + boolean sourceVersionAtLeast19 = versionInformation.isSourceVersionAtLeast19(); + implementationTypes.put( + Set.class.getName(), + sourceVersionAtLeast19 ? + withFactoryMethod( getType( LinkedHashSet.class ), LINKED_HASH_SET_FACTORY_METHOD_NAME ) : + withLoadFactorAdjustment( getType( LinkedHashSet.class ) ) + ); implementationTypes.put( SortedSet.class.getName(), withDefaultConstructor( getType( TreeSet.class ) ) ); implementationTypes.put( NavigableSet.class.getName(), withDefaultConstructor( getType( TreeSet.class ) ) ); - implementationTypes.put( Map.class.getName(), withLoadFactorAdjustment( getType( HashMap.class ) ) ); + implementationTypes.put( + Map.class.getName(), + sourceVersionAtLeast19 ? + withFactoryMethod( getType( LinkedHashMap.class ), LINKED_HASH_MAP_FACTORY_METHOD_NAME ) : + withLoadFactorAdjustment( getType( LinkedHashMap.class ) ) + ); implementationTypes.put( SortedMap.class.getName(), withDefaultConstructor( getType( TreeMap.class ) ) ); implementationTypes.put( NavigableMap.class.getName(), withDefaultConstructor( getType( TreeMap.class ) ) ); implementationTypes.put( @@ -131,6 +150,16 @@ public TypeFactory(Elements elementUtils, Types typeUtils, FormattingMessager me ConcurrentNavigableMap.class.getName(), withDefaultConstructor( getType( ConcurrentSkipListMap.class ) ) ); + implementationTypes.put( + JavaCollectionConstants.SEQUENCED_SET_FQN, + withFactoryMethod( getType( LinkedHashSet.class ), LINKED_HASH_SET_FACTORY_METHOD_NAME ) + ); + implementationTypes.put( + JavaCollectionConstants.SEQUENCED_MAP_FQN, + withFactoryMethod( getType( LinkedHashMap.class ), LINKED_HASH_MAP_FACTORY_METHOD_NAME ) + ); + + this.loggingVerbose = loggingVerbose; } public Type getTypeForLiteral(Class type) { @@ -158,7 +187,6 @@ private Type getType(String canonicalName, boolean isLiteral) { return getType( typeElement, isLiteral ); } - /** * Determines if the type with the given full qualified name is part of the classpath * @@ -190,18 +218,34 @@ public Type getType(TypeMirror mirror) { return getType( mirror, false ); } + /** + * Return a type that is always going to be imported. + * This is useful when using it in {@code Mapper#imports} + * for types that should be used in expressions. + * + * @param mirror the type mirror for which we need a type + * + * @return the type + */ + public Type getAlwaysImportedType(TypeMirror mirror) { + return getType( mirror, false, true ); + } + private Type getType(TypeMirror mirror, boolean isLiteral) { + return getType( mirror, isLiteral, null ); + } + + private Type getType(TypeMirror mirror, boolean isLiteral, Boolean alwaysImport) { if ( !canBeProcessed( mirror ) ) { throw new TypeHierarchyErroneousException( mirror ); } ImplementationType implementationType = getImplementationType( mirror ); - BuilderInfo builderInfo = findBuilder( mirror ); - boolean isIterableType = typeUtils.isSubtype( mirror, iterableType ); - boolean isCollectionType = typeUtils.isSubtype( mirror, collectionType ); - boolean isMapType = typeUtils.isSubtype( mirror, mapType ); - boolean isStreamType = streamType != null && typeUtils.isSubtype( mirror, streamType ); + boolean isIterableType = typeUtils.isSubtypeErased( mirror, iterableType ); + boolean isCollectionType = typeUtils.isSubtypeErased( mirror, collectionType ); + boolean isMapType = typeUtils.isSubtypeErased( mirror, mapType ); + boolean isStreamType = streamType != null && typeUtils.isSubtypeErased( mirror, streamType ); boolean isEnumType; boolean isInterface; @@ -210,7 +254,7 @@ private Type getType(TypeMirror mirror, boolean isLiteral) { String qualifiedName; TypeElement typeElement; Type componentType; - boolean isImported; + Boolean toBeImported = alwaysImport; if ( mirror.getKind() == TypeKind.DECLARED ) { DeclaredType declaredType = (DeclaredType) mirror; @@ -231,7 +275,6 @@ private Type getType(TypeMirror mirror, boolean isLiteral) { } componentType = null; - isImported = isImported( name, qualifiedName ); } else if ( mirror.getKind() == TypeKind.ARRAY ) { TypeMirror componentTypeMirror = getComponentType( mirror ); @@ -250,13 +293,21 @@ else if ( mirror.getKind() == TypeKind.ARRAY ) { name = componentTypeElement.getSimpleName().toString() + arraySuffix; packageName = elementUtils.getPackageOf( componentTypeElement ).getQualifiedName().toString(); qualifiedName = componentTypeElement.getQualifiedName().toString() + arraySuffix; - isImported = isImported( name, qualifiedName ); + } + else if ( componentTypeMirror.getKind().isPrimitive() ) { + // When the component type is primitive and is annotated with ElementType.TYPE_USE then + // the typeMirror#toString returns (@CustomAnnotation :: byte) for the javac compiler + name = NativeTypes.getName( componentTypeMirror.getKind() ) + builder.toString(); + packageName = null; + // for primitive types only name (e.g. byte, short..) required as qualified name + qualifiedName = name; + toBeImported = false; } else { name = mirror.toString(); packageName = null; qualifiedName = name; - isImported = false; + toBeImported = false; } isEnumType = false; @@ -267,12 +318,24 @@ else if ( mirror.getKind() == TypeKind.ARRAY ) { else { isEnumType = false; isInterface = false; - name = mirror.toString(); + // When the component type is primitive and is annotated with ElementType.TYPE_USE then + // the typeMirror#toString returns (@CustomAnnotation :: byte) for the javac compiler + if ( mirror.getKind().isPrimitive() ) { + name = NativeTypes.getName( mirror.getKind() ); + } + // When the component type is type var and is annotated with ElementType.TYPE_USE then + // the typeMirror#toString returns (@CustomAnnotation T) for the errorprone javac compiler + else if ( mirror.getKind() == TypeKind.TYPEVAR ) { + name = ( (TypeVariable) mirror ).asElement().getSimpleName().toString(); + } + else { + name = mirror.toString(); + } packageName = null; qualifiedName = name; typeElement = null; componentType = null; - isImported = false; + toBeImported = false; } return new Type( @@ -283,7 +346,6 @@ else if ( mirror.getKind() == TypeKind.ARRAY ) { getTypeParameters( mirror, false ), implementationType, componentType, - builderInfo, packageName, name, qualifiedName, @@ -293,8 +355,11 @@ else if ( mirror.getKind() == TypeKind.ARRAY ) { isCollectionType, isMapType, isStreamType, - isImported, - isLiteral + toBeImportedTypes, + notToBeImportedTypes, + toBeImported, + isLiteral, + loggingVerbose ); } @@ -355,10 +420,10 @@ public TypeMirror getMethodType(DeclaredType includingType, Element method) { } public Parameter getSingleParameter(DeclaredType includingType, Accessor method) { - ExecutableElement executable = method.getExecutable(); - if ( executable == null ) { + if ( method.getAccessorType().isFieldAssignment() ) { return null; } + ExecutableElement executable = (ExecutableElement) method.getElement(); List parameters = executable.getParameters(); if ( parameters.size() != 1 ) { @@ -370,27 +435,37 @@ public Parameter getSingleParameter(DeclaredType includingType, Accessor method) } public List getParameters(DeclaredType includingType, Accessor accessor) { - ExecutableElement method = accessor.getExecutable(); - TypeMirror methodType = getMethodType( includingType, accessor.getElement() ); + ExecutableElement method = (ExecutableElement) accessor.getElement(); + return getParameters( includingType, method ); + } + + public List getParameters(DeclaredType includingType, ExecutableElement method) { + ExecutableType methodType = getMethodType( includingType, method ); if ( method == null || methodType.getKind() != TypeKind.EXECUTABLE ) { - return new ArrayList(); + return new ArrayList<>(); } - return getParameters( (ExecutableType) methodType, method ); + return getParameters( methodType, method ); } public List getParameters(ExecutableType methodType, ExecutableElement method) { List parameterTypes = methodType.getParameterTypes(); List parameters = method.getParameters(); - List result = new ArrayList( parameters.size() ); + List result = new ArrayList<>( parameters.size() ); Iterator varIt = parameters.iterator(); Iterator typesIt = parameterTypes.iterator(); - for ( ; varIt.hasNext(); ) { + while ( varIt.hasNext() ) { VariableElement parameter = varIt.next(); TypeMirror parameterType = typesIt.next(); - result.add( Parameter.forElementAndType( parameter, getType( parameterType ) ) ); + Type type = getType( parameterType ); + + // if the method has varargs and this is the last parameter + // we know that this parameter should be used as varargs + boolean isVarArgs = !varIt.hasNext() && method.isVarArgs(); + + result.add( Parameter.forElementAndType( parameter, type, isVarArgs ) ); } return result; @@ -422,37 +497,41 @@ public List getThrownTypes(ExecutableType method) { } public List getThrownTypes(Accessor accessor) { - if (accessor.getExecutable() == null) { - return new ArrayList(); + if ( accessor.getAccessorType().isFieldAssignment() ) { + return new ArrayList<>(); } - return extractTypes( accessor.getExecutable().getThrownTypes() ); + Element element = accessor.getElement(); + if ( element instanceof ExecutableElement ) { + return extractTypes( ( (ExecutableElement) element ).getThrownTypes() ); + } + return new ArrayList<>(); } private List extractTypes(List typeMirrors) { - Set types = new HashSet( typeMirrors.size() ); + Set types = new HashSet<>( typeMirrors.size() ); for ( TypeMirror typeMirror : typeMirrors ) { types.add( getType( typeMirror ) ); } - return new ArrayList( types ); + return new ArrayList<>( types ); } private List getTypeParameters(TypeMirror mirror, boolean isImplementationType) { + while ( mirror.getKind() == TypeKind.ARRAY ) { + mirror = getComponentType( mirror ); + } if ( mirror.getKind() != TypeKind.DECLARED ) { return java.util.Collections.emptyList(); } DeclaredType declaredType = (DeclaredType) mirror; - List typeParameters = new ArrayList( declaredType.getTypeArguments().size() ); + List typeArguments = declaredType.getTypeArguments(); + List typeParameters = new ArrayList<>( typeArguments.size() ); - for ( TypeMirror typeParameter : declaredType.getTypeArguments() ) { - if ( isImplementationType ) { - typeParameters.add( getType( typeParameter ).getTypeBound() ); - } - else { - typeParameters.add( getType( typeParameter ) ); - } + for ( TypeMirror typeParameter : typeArguments ) { + Type type = getType( typeParameter ); + typeParameters.add( isImplementationType ? type.getTypeBound() : type ); } return typeParameters; @@ -497,7 +576,6 @@ private ImplementationType getImplementationType(TypeMirror mirror) { getTypeParameters( mirror, true ), null, null, - null, implementationType.getPackageName(), implementationType.getName(), implementationType.getFullyQualifiedName(), @@ -507,8 +585,11 @@ private ImplementationType getImplementationType(TypeMirror mirror) { implementationType.isCollectionType(), implementationType.isMapType(), implementationType.isStreamType(), - isImported( implementationType.getName(), implementationType.getFullyQualifiedName() ), - implementationType.isLiteral() + toBeImportedTypes, + notToBeImportedTypes, + null, + implementationType.isLiteral(), + loggingVerbose ); return implementation.createNew( replacement ); } @@ -516,19 +597,24 @@ private ImplementationType getImplementationType(TypeMirror mirror) { return null; } - private BuilderInfo findBuilder(TypeMirror type) { + private BuilderInfo findBuilder(TypeMirror type, BuilderGem builderGem, boolean report) { + if ( builderGem != null && builderGem.disableBuilder().get() ) { + return null; + } try { return roundContext.getAnnotationProcessorContext() .getBuilderProvider() - .findBuilderInfo( type, elementUtils, typeUtils ); + .findBuilderInfo( type ); } catch ( MoreThanOneBuilderCreationMethodException ex ) { - messager.printMessage( - typeUtils.asElement( type ), - Message.BUILDER_MORE_THAN_ONE_BUILDER_CREATION_METHOD, - type, - Strings.join( ex.getBuilderInfo(), ", ", BUILDER_INFO_CREATION_METHOD_EXTRACTOR ) - ); + if ( report ) { + messager.printMessage( + typeUtils.asElement( type ), + Message.BUILDER_MORE_THAN_ONE_BUILDER_CREATION_METHOD, + type, + Strings.join( ex.getBuilderInfo(), ", ", BUILDER_INFO_CREATION_METHOD_EXTRACTOR ) + ); + } } return null; @@ -543,56 +629,6 @@ private TypeMirror getComponentType(TypeMirror mirror) { return arrayType.getComponentType(); } - private boolean isImported(String name, String qualifiedName) { - String trimmedName = TypeFactory.trimSimpleClassName( name ); - String trimmedQualifiedName = TypeFactory.trimSimpleClassName( qualifiedName ); - String importedType = importedQualifiedTypesBySimpleName.get( trimmedName ); - - boolean imported = false; - if ( importedType != null ) { - if ( importedType.equals( trimmedQualifiedName ) ) { - imported = true; - } - } - else { - importedQualifiedTypesBySimpleName.put( trimmedName, trimmedQualifiedName ); - imported = true; - } - return imported; - } - - /** - * Converts any collection type, e.g. {@code List} to {@code Collection} and any map type, e.g. - * {@code HashMap} to {@code Map}. - * - * @param collectionOrMap any collection or map type - * @return the type representing {@code Collection} or {@code Map}, if the argument type is a subtype of - * {@code Collection} or of {@code Map} respectively. - */ - public Type asCollectionOrMap(Type collectionOrMap) { - List originalParameters = collectionOrMap.getTypeParameters(); - TypeMirror[] originalParameterMirrors = new TypeMirror[originalParameters.size()]; - int i = 0; - for ( Type param : originalParameters ) { - originalParameterMirrors[i++] = param.getTypeMirror(); - } - - if ( collectionOrMap.isCollectionType() - && !"java.util.Collection".equals( collectionOrMap.getFullyQualifiedName() ) ) { - return getType( typeUtils.getDeclaredType( - elementUtils.getTypeElement( "java.util.Collection" ), - originalParameterMirrors ) ); - } - else if ( collectionOrMap.isMapType() - && !"java.util.Map".equals( collectionOrMap.getFullyQualifiedName() ) ) { - return getType( typeUtils.getDeclaredType( - elementUtils.getTypeElement( "java.util.Map" ), - originalParameterMirrors ) ); - } - - return collectionOrMap; - } - /** * creates a void return type * @@ -635,36 +671,16 @@ else if ( typeMirror.getKind() == TypeKind.TYPEVAR ) { if ( typeVariableType.getUpperBound() != null ) { return typeVariableType.getUpperBound(); } - // Lowerbounds intentionally left out: Type variables otherwise have a lower bound of NullType. + // lower bounds ( T super Number ) cannot be used for argument parameters, but can be used for + // method parameters: e.g. T map (T in); + if ( typeVariableType.getLowerBound() != null ) { + return typeVariableType.getLowerBound(); + } } return typeMirror; } - /** - * It strips the all the {@code []} from the {@code className}. - * - * E.g. - *
    -     *     trimSimpleClassName("String[][][]") -> "String"
    -     *     trimSimpleClassName("String[]") -> "String"
    -     * 
    - * - * @param className that needs to be trimmed - * - * @return the trimmed {@code className}, or {@code null} if the {@code className} was {@code null} - */ - static String trimSimpleClassName(String className) { - if ( className == null ) { - return null; - } - String trimmedClassName = className; - while ( trimmedClassName.endsWith( "[]" ) ) { - trimmedClassName = trimmedClassName.substring( 0, trimmedClassName.length() - 2 ); - } - return trimmedClassName; - } - /** * Whether the given type is ready to be processed or not. It can be processed if it is not of kind * {@link TypeKind#ERROR} and all {@link AstModifyingAnnotationProcessor}s (if any) indicated that they've fully @@ -697,4 +713,21 @@ private boolean canBeProcessed(TypeMirror type) { return true; } + + public BuilderType builderTypeFor( Type type, BuilderGem builder ) { + if ( type != null ) { + BuilderInfo builderInfo = findBuilder( type.getTypeMirror(), builder, true ); + return BuilderType.create( builderInfo, type, this, this.typeUtils ); + } + return null; + } + + public Type effectiveResultTypeFor( Type type, BuilderGem builder ) { + if ( type != null ) { + BuilderInfo builderInfo = findBuilder( type.getTypeMirror(), builder, false ); + BuilderType builderType = BuilderType.create( builderInfo, type, this, this.typeUtils ); + return builderType != null ? builderType.getBuilder() : type; + } + return type; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/common/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/common/package-info.java index 82cda989a4..32be1929a9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/common/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/common/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

    diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/GraphAnalyzer.java b/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/GraphAnalyzer.java index 9b8bf28575..06acfc24b5 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/GraphAnalyzer.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/GraphAnalyzer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.dependency; @@ -22,6 +9,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -41,8 +29,8 @@ public class GraphAnalyzer { private GraphAnalyzer(Map nodes) { this.nodes = nodes; - cycles = new HashSet>(); - currentPath = new Stack(); + cycles = new HashSet<>(); + currentPath = new Stack<>(); } public static GraphAnalyzerBuilder builder() { @@ -107,7 +95,7 @@ private void depthFirstSearch(Node node) { } private List getCurrentCycle(Node start) { - List cycle = new ArrayList(); + List cycle = new ArrayList<>(); boolean inCycle = false; for ( Node n : currentPath ) { @@ -125,20 +113,20 @@ private List getCurrentCycle(Node start) { public static class GraphAnalyzerBuilder { - private final Map nodes = new LinkedHashMap(); + private final Map nodes = new LinkedHashMap<>(); - public GraphAnalyzerBuilder withNode(String name, List descendants) { - Node node = getNode( name ); + public GraphAnalyzerBuilder withNode(String name, Set descendants) { + Node node = nodes.computeIfAbsent( name, Node::new ); for ( String descendant : descendants ) { - node.addDescendant( getNode( descendant ) ); + node.addDescendant( nodes.computeIfAbsent( descendant, Node::new ) ); } return this; } public GraphAnalyzerBuilder withNode(String name, String... descendants) { - return withNode( name, Arrays.asList( descendants ) ); + return withNode( name, new LinkedHashSet<>( Arrays.asList( descendants ) ) ); } /** @@ -152,16 +140,5 @@ public GraphAnalyzer build() { graphAnalyzer.analyze(); return graphAnalyzer; } - - private Node getNode(String name) { - Node node = nodes.get( name ); - - if ( node == null ) { - node = new Node( name ); - nodes.put( name, node ); - } - - return node; - } } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/Node.java b/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/Node.java index 0cc35e6308..883731ac7c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/Node.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/dependency/Node.java @@ -1,25 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.dependency; import java.util.ArrayList; import java.util.List; +import java.util.Objects; /** * A node of a directed graph. @@ -39,7 +27,7 @@ class Node { Node(String name) { this.name = name; - descendants = new ArrayList(); + descendants = new ArrayList<>(); } public String getName() { @@ -99,14 +87,11 @@ public boolean equals(Object obj) { return false; } Node other = (Node) obj; - if ( name == null ) { - if ( other.name != null ) { - return false; - } - } - else if ( !name.equals( other.name ) ) { + + if ( !Objects.equals( name, other.name ) ) { return false; } + return true; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/package-info.java index 9f172edf79..06e132833c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

    diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/presence/AllPresenceChecksPresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/AllPresenceChecksPresenceCheck.java new file mode 100644 index 0000000000..d71f67a2a4 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/AllPresenceChecksPresenceCheck.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.presence; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.NegatePresenceCheck; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A {@link PresenceCheck} that checks if all the given presence checks are present. + * + * @author Filip Hrisafov + */ +public class AllPresenceChecksPresenceCheck extends ModelElement implements PresenceCheck { + + private final Collection presenceChecks; + + public AllPresenceChecksPresenceCheck(Collection presenceChecks) { + this.presenceChecks = presenceChecks; + } + + public Collection getPresenceChecks() { + return presenceChecks; + } + + @Override + public PresenceCheck negate() { + return new NegatePresenceCheck( this ); + } + + @Override + public Set getImportTypes() { + Set importTypes = new HashSet<>(); + for ( PresenceCheck presenceCheck : presenceChecks ) { + importTypes.addAll( presenceCheck.getImportTypes() ); + } + + return importTypes; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + AllPresenceChecksPresenceCheck that = (AllPresenceChecksPresenceCheck) o; + return Objects.equals( presenceChecks, that.presenceChecks ); + } + + @Override + public int hashCode() { + return Objects.hash( presenceChecks ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/presence/AnyPresenceChecksPresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/AnyPresenceChecksPresenceCheck.java new file mode 100644 index 0000000000..5f8fac9623 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/AnyPresenceChecksPresenceCheck.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.presence; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.NegatePresenceCheck; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A {@link PresenceCheck} that checks if any of the given presence checks are present. + * + * @author Filip Hrisafov + */ +public class AnyPresenceChecksPresenceCheck extends ModelElement implements PresenceCheck { + + private final Collection presenceChecks; + + public AnyPresenceChecksPresenceCheck(Collection presenceChecks) { + this.presenceChecks = presenceChecks; + } + + public Collection getPresenceChecks() { + return presenceChecks; + } + + @Override + public PresenceCheck negate() { + return new NegatePresenceCheck( this ); + } + + @Override + public Set getImportTypes() { + Set importTypes = new HashSet<>(); + for ( PresenceCheck presenceCheck : presenceChecks ) { + importTypes.addAll( presenceCheck.getImportTypes() ); + } + + return importTypes; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + AnyPresenceChecksPresenceCheck that = (AnyPresenceChecksPresenceCheck) o; + return Objects.equals( presenceChecks, that.presenceChecks ); + } + + @Override + public int hashCode() { + return Objects.hash( presenceChecks ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/presence/JavaExpressionPresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/JavaExpressionPresenceCheck.java new file mode 100644 index 0000000000..0c7c132023 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/JavaExpressionPresenceCheck.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.presence; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.NegatePresenceCheck; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A {@link PresenceCheck} that calls a Java expression. + * + * @author Filip Hrisafov + */ +public class JavaExpressionPresenceCheck extends ModelElement implements PresenceCheck { + + private final String javaExpression; + + public JavaExpressionPresenceCheck(String javaExpression) { + this.javaExpression = javaExpression; + } + + public String getJavaExpression() { + return javaExpression; + } + + @Override + public PresenceCheck negate() { + return new NegatePresenceCheck( this ); + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + JavaExpressionPresenceCheck that = (JavaExpressionPresenceCheck) o; + return Objects.equals( javaExpression, that.javaExpression ); + } + + @Override + public int hashCode() { + return Objects.hash( javaExpression ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/presence/NullPresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/NullPresenceCheck.java new file mode 100644 index 0000000000..2da4ae4023 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/NullPresenceCheck.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.presence; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A presence check that checks if the source reference is null. + * + * @author Filip Hrisafov + */ +public class NullPresenceCheck extends ModelElement implements PresenceCheck { + + private final String sourceReference; + private final boolean negate; + + public NullPresenceCheck(String sourceReference) { + this.sourceReference = sourceReference; + this.negate = false; + } + + public NullPresenceCheck(String sourceReference, boolean negate) { + this.sourceReference = sourceReference; + this.negate = negate; + } + + public String getSourceReference() { + return sourceReference; + } + + public boolean isNegate() { + return negate; + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + @Override + public PresenceCheck negate() { + return new NullPresenceCheck( sourceReference, !negate ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + NullPresenceCheck that = (NullPresenceCheck) o; + return Objects.equals( sourceReference, that.sourceReference ); + } + + @Override + public int hashCode() { + return Objects.hash( sourceReference ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/presence/OptionalPresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/OptionalPresenceCheck.java new file mode 100644 index 0000000000..d727c30f24 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/OptionalPresenceCheck.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.presence; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.version.VersionInformation; + +/** + * Presence checker for {@link java.util.Optional} types. + * + * @author Ken Wang + */ +public class OptionalPresenceCheck extends ModelElement implements PresenceCheck { + + private final String sourceReference; + private final VersionInformation versionInformation; + private final boolean negate; + + public OptionalPresenceCheck(String sourceReference, VersionInformation versionInformation) { + this( sourceReference, versionInformation, false ); + } + + public OptionalPresenceCheck(String sourceReference, VersionInformation versionInformation, boolean negate) { + this.sourceReference = sourceReference; + this.versionInformation = versionInformation; + this.negate = negate; + } + + public String getSourceReference() { + return sourceReference; + } + + public VersionInformation getVersionInformation() { + return versionInformation; + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + public boolean isNegate() { + return negate; + } + + @Override + public PresenceCheck negate() { + return new OptionalPresenceCheck( sourceReference, versionInformation, !negate ); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + OptionalPresenceCheck that = (OptionalPresenceCheck) o; + return Objects.equals( sourceReference, that.sourceReference ); + } + + @Override + public int hashCode() { + return Objects.hash( sourceReference ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/presence/SuffixPresenceCheck.java b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/SuffixPresenceCheck.java new file mode 100644 index 0000000000..d35e89fce2 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/presence/SuffixPresenceCheck.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.presence; + +import java.util.Collections; +import java.util.Objects; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ModelElement; +import org.mapstruct.ap.internal.model.common.NegatePresenceCheck; +import org.mapstruct.ap.internal.model.common.PresenceCheck; +import org.mapstruct.ap.internal.model.common.Type; + +/** + * A {@link PresenceCheck} that calls the suffix on the source reference. + * + * @author Filip Hrisafov + */ +public class SuffixPresenceCheck extends ModelElement implements PresenceCheck { + + private final String sourceReference; + private final String suffix; + private final boolean negate; + + public SuffixPresenceCheck(String sourceReference, String suffix) { + this( sourceReference, suffix, false ); + } + + public SuffixPresenceCheck(String sourceReference, String suffix, boolean negate) { + this.sourceReference = sourceReference; + this.suffix = suffix; + this.negate = negate; + } + + public String getSourceReference() { + return sourceReference; + } + + public String getSuffix() { + return suffix; + } + + public boolean isNegate() { + return negate; + } + + @Override + public PresenceCheck negate() { + return new NegatePresenceCheck( this ); + } + + @Override + public Set getImportTypes() { + return Collections.emptySet(); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SuffixPresenceCheck that = (SuffixPresenceCheck) o; + return Objects.equals( sourceReference, that.sourceReference ) + && Objects.equals( suffix, that.suffix ); + } + + @Override + public int hashCode() { + return Objects.hash( sourceReference, suffix ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/BeanMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/BeanMapping.java deleted file mode 100644 index a181c3a995..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/BeanMapping.java +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import java.util.Collections; -import java.util.List; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.type.TypeKind; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.prism.BeanMappingPrism; -import org.mapstruct.ap.internal.prism.BuilderPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; -import org.mapstruct.ap.internal.prism.ReportingPolicyPrism; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; - -/** - * Represents an bean mapping as configured via {@code @BeanMapping}. - * - * @author Sjaak Derksen - */ -public class BeanMapping { - - private final SelectionParameters selectionParameters; - private final NullValueMappingStrategyPrism nullValueMappingStrategy; - private final ReportingPolicyPrism reportingPolicy; - private final boolean ignoreByDefault; - private final List ignoreUnmappedSourceProperties; - private final BuilderPrism builder; - - /** - * creates a mapping for inheritance. Will set ignoreByDefault to false. - * - * @param map - * @return - */ - public static BeanMapping forInheritance( BeanMapping map ) { - return new BeanMapping( - map.selectionParameters, - map.nullValueMappingStrategy, - map.reportingPolicy, - false, - map.ignoreUnmappedSourceProperties, - map.builder - ); - } - - public static BeanMapping fromPrism(BeanMappingPrism beanMapping, ExecutableElement method, - FormattingMessager messager, Types typeUtils) { - - if ( beanMapping == null ) { - return null; - } - - boolean resultTypeIsDefined = !TypeKind.VOID.equals( beanMapping.resultType().getKind() ); - - NullValueMappingStrategyPrism nullValueMappingStrategy = - null == beanMapping.values.nullValueMappingStrategy() - ? null - : NullValueMappingStrategyPrism.valueOf( beanMapping.nullValueMappingStrategy() ); - - boolean ignoreByDefault = beanMapping.ignoreByDefault(); - BuilderPrism builderMapping = null; - if ( beanMapping.values.builder() != null ) { - builderMapping = beanMapping.builder(); - } - - if ( !resultTypeIsDefined && beanMapping.qualifiedBy().isEmpty() && beanMapping.qualifiedByName().isEmpty() - && beanMapping.ignoreUnmappedSourceProperties().isEmpty() - && ( nullValueMappingStrategy == null ) && !ignoreByDefault - && builderMapping == null ) { - - messager.printMessage( method, Message.BEANMAPPING_NO_ELEMENTS ); - } - - SelectionParameters cmp = new SelectionParameters( - beanMapping.qualifiedBy(), - beanMapping.qualifiedByName(), - resultTypeIsDefined ? beanMapping.resultType() : null, - typeUtils - ); - - //TODO Do we want to add the reporting policy to the BeanMapping as well? To give more granular support? - return new BeanMapping( - cmp, - nullValueMappingStrategy, - null, - ignoreByDefault, - beanMapping.ignoreUnmappedSourceProperties(), - builderMapping - ); - } - - /** - * This method should be used to generate BeanMappings for our internal generated Mappings. Like forged update - * methods. - * - * @return bean mapping that needs to be used for Mappings - */ - public static BeanMapping forForgedMethods() { - return new BeanMapping( null, null, ReportingPolicyPrism.IGNORE, false, Collections.emptyList(), null ); - } - - private BeanMapping(SelectionParameters selectionParameters, NullValueMappingStrategyPrism nvms, - ReportingPolicyPrism reportingPolicy, boolean ignoreByDefault, - List ignoreUnmappedSourceProperties, BuilderPrism builder) { - this.selectionParameters = selectionParameters; - this.nullValueMappingStrategy = nvms; - this.reportingPolicy = reportingPolicy; - this.ignoreByDefault = ignoreByDefault; - this.ignoreUnmappedSourceProperties = ignoreUnmappedSourceProperties; - this.builder = builder; - } - - public SelectionParameters getSelectionParameters() { - return selectionParameters; - } - - public NullValueMappingStrategyPrism getNullValueMappingStrategy() { - return nullValueMappingStrategy; - } - - public ReportingPolicyPrism getReportingPolicy() { - return reportingPolicy; - } - - public boolean isignoreByDefault() { - return ignoreByDefault; - } - - public List getIgnoreUnmappedSourceProperties() { - return ignoreUnmappedSourceProperties; - } - - public BuilderPrism getBuilder() { - return builder; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/BeanMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/BeanMappingOptions.java new file mode 100644 index 0000000000..73a4d7c12d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/BeanMappingOptions.java @@ -0,0 +1,253 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.BeanMappingGem; +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; +import org.mapstruct.ap.internal.gem.SubclassExhaustiveStrategyGem; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.tools.gem.GemValue; + +/** + * Represents an bean mapping as configured via {@code @BeanMapping}. + * + * @author Sjaak Derksen + */ +public class BeanMappingOptions extends DelegatingOptions { + + private final SelectionParameters selectionParameters; + private final List ignoreUnmappedSourceProperties; + private final BeanMappingGem beanMapping; + + /** + * creates a mapping for inheritance. Will set + * + * @param beanMapping the bean mapping options that should be used + * @param isInverse whether the inheritance is inverse + * + * @return new mapping + */ + public static BeanMappingOptions forInheritance(BeanMappingOptions beanMapping, boolean isInverse) { + BeanMappingOptions options = new BeanMappingOptions( + SelectionParameters.forInheritance( beanMapping.selectionParameters ), + isInverse ? Collections.emptyList() : beanMapping.ignoreUnmappedSourceProperties, + beanMapping.beanMapping, + beanMapping + ); + return options; + } + + public static BeanMappingOptions forForgedMethods(BeanMappingOptions beanMapping) { + BeanMappingOptions options = new BeanMappingOptions( + beanMapping.selectionParameters != null ? + SelectionParameters.withoutResultType( beanMapping.selectionParameters ) : SelectionParameters.empty(), + Collections.emptyList(), + beanMapping.beanMapping, + beanMapping + ); + return options; + } + + public static BeanMappingOptions forSubclassForgedMethods(BeanMappingOptions beanMapping) { + + return new BeanMappingOptions( + beanMapping.selectionParameters != null ? + SelectionParameters.withoutResultType( beanMapping.selectionParameters ) : null, + beanMapping.ignoreUnmappedSourceProperties, + beanMapping.beanMapping, + beanMapping + ); + } + + public static BeanMappingOptions empty(DelegatingOptions delegatingOptions) { + return new BeanMappingOptions( SelectionParameters.empty(), Collections.emptyList(), null, delegatingOptions ); + } + + public static BeanMappingOptions getInstanceOn(BeanMappingGem beanMapping, MapperOptions mapperOptions, + ExecutableElement method, FormattingMessager messager, + TypeUtils typeUtils, TypeFactory typeFactory + ) { + if ( beanMapping == null || !isConsistent( beanMapping, method, messager ) ) { + return empty( mapperOptions ); + } + + Objects.requireNonNull( method ); + Objects.requireNonNull( messager ); + Objects.requireNonNull( method ); + Objects.requireNonNull( typeUtils ); + Objects.requireNonNull( typeFactory ); + + SelectionParameters selectionParameters = new SelectionParameters( + beanMapping.qualifiedBy().get(), + beanMapping.qualifiedByName().get(), + beanMapping.resultType().getValue(), + typeUtils + ); + + //TODO Do we want to add the reporting policy to the BeanMapping as well? To give more granular support? + BeanMappingOptions options = new BeanMappingOptions( + selectionParameters, + beanMapping.ignoreUnmappedSourceProperties().get(), + beanMapping, + mapperOptions + ); + return options; + } + + private static boolean isConsistent(BeanMappingGem gem, ExecutableElement method, + FormattingMessager messager) { + if ( !gem.resultType().hasValue() + && !gem.mappingControl().hasValue() + && !gem.qualifiedBy().hasValue() + && !gem.qualifiedByName().hasValue() + && !gem.ignoreUnmappedSourceProperties().hasValue() + && !gem.nullValueCheckStrategy().hasValue() + && !gem.nullValuePropertyMappingStrategy().hasValue() + && !gem.nullValueMappingStrategy().hasValue() + && !gem.subclassExhaustiveStrategy().hasValue() + && !gem.unmappedTargetPolicy().hasValue() + && !gem.unmappedSourcePolicy().hasValue() + && !gem.ignoreByDefault().hasValue() + && !gem.builder().hasValue() ) { + + messager.printMessage( method, Message.BEANMAPPING_NO_ELEMENTS ); + return false; + } + return true; + } + + private BeanMappingOptions(SelectionParameters selectionParameters, + List ignoreUnmappedSourceProperties, + BeanMappingGem beanMapping, + DelegatingOptions next) { + super( next ); + this.selectionParameters = selectionParameters; + this.ignoreUnmappedSourceProperties = ignoreUnmappedSourceProperties; + this.beanMapping = beanMapping; + } + + // @Mapping, @BeanMapping + + @Override + public NullValueCheckStrategyGem getNullValueCheckStrategy() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::nullValueCheckStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValueCheckStrategyGem::valueOf ) + .orElse( next().getNullValueCheckStrategy() ); + } + + @Override + public NullValuePropertyMappingStrategyGem getNullValuePropertyMappingStrategy() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::nullValuePropertyMappingStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValuePropertyMappingStrategyGem::valueOf ) + .orElse( next().getNullValuePropertyMappingStrategy() ); + } + + @Override + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::nullValueMappingStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValueMappingStrategyGem::valueOf ) + .orElse( next().getNullValueMappingStrategy() ); + } + + @Override + public SubclassExhaustiveStrategyGem getSubclassExhaustiveStrategy() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::subclassExhaustiveStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( SubclassExhaustiveStrategyGem::valueOf ) + .orElse( next().getSubclassExhaustiveStrategy() ); + } + + @Override + public TypeMirror getSubclassExhaustiveException() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::subclassExhaustiveException ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .orElse( next().getSubclassExhaustiveException() ); + } + + @Override + public ReportingPolicyGem unmappedTargetPolicy() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::unmappedTargetPolicy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( ReportingPolicyGem::valueOf ) + .orElse( next().unmappedTargetPolicy() ); + } + + @Override + public ReportingPolicyGem unmappedSourcePolicy() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::unmappedSourcePolicy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( ReportingPolicyGem::valueOf ) + .orElse( next().unmappedSourcePolicy() ); + } + + @Override + public BuilderGem getBuilder() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::builder ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .orElse( next().getBuilder() ); + } + + @Override + public MappingControl getMappingControl(ElementUtils elementUtils) { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::mappingControl ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( mc -> MappingControl.fromTypeMirror( mc, elementUtils ) ) + .orElse( next().getMappingControl( elementUtils ) ); + } + + // @BeanMapping specific + + public SelectionParameters getSelectionParameters() { + return selectionParameters; + } + + public boolean isIgnoredByDefault() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::ignoreByDefault ) + .map( GemValue::get ) + .orElse( false ); + } + + public List getIgnoreUnmappedSourceProperties() { + return ignoreUnmappedSourceProperties; + } + + public AnnotationMirror getMirror() { + return Optional.ofNullable( beanMapping ).map( BeanMappingGem::mirror ).orElse( null ); + } + + @Override + public boolean hasAnnotation() { + return beanMapping != null; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ConditionMethodOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ConditionMethodOptions.java new file mode 100644 index 0000000000..dfb0865ecc --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ConditionMethodOptions.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Collection; +import java.util.Collections; + +import org.mapstruct.ap.internal.gem.ConditionStrategyGem; + +/** + * Encapsulates all options specific for a condition check method. + * + * @author Filip Hrisafov + */ +public class ConditionMethodOptions { + + private static final ConditionMethodOptions EMPTY = new ConditionMethodOptions( Collections.emptyList() ); + + private final Collection conditionOptions; + + public ConditionMethodOptions(Collection conditionOptions) { + this.conditionOptions = conditionOptions; + } + + public boolean isStrategyApplicable(ConditionStrategyGem strategy) { + for ( ConditionOptions conditionOption : conditionOptions ) { + if ( conditionOption.getConditionStrategies().contains( strategy ) ) { + return true; + } + } + + return false; + } + + public boolean isAnyStrategyApplicable() { + return !conditionOptions.isEmpty(); + } + + public static ConditionMethodOptions empty() { + return EMPTY; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ConditionOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ConditionOptions.java new file mode 100644 index 0000000000..83e2bf2819 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ConditionOptions.java @@ -0,0 +1,172 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Collection; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.ConditionGem; +import org.mapstruct.ap.internal.gem.ConditionStrategyGem; +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; + +/** + * Represents a condition configuration as configured via {@code @Condition}. + * + * @author Filip Hrisafov + */ +public class ConditionOptions { + + private final Set conditionStrategies; + + private ConditionOptions(Set conditionStrategies) { + this.conditionStrategies = conditionStrategies; + } + + public Collection getConditionStrategies() { + return conditionStrategies; + } + + public static ConditionOptions getInstanceOn(ConditionGem condition, ExecutableElement method, + List parameters, + FormattingMessager messager) { + if ( condition == null ) { + return null; + } + + TypeMirror returnType = method.getReturnType(); + TypeKind returnTypeKind = returnType.getKind(); + // We only allow methods that return boolean or Boolean to be condition methods + if ( returnTypeKind != TypeKind.BOOLEAN ) { + if ( returnTypeKind != TypeKind.DECLARED ) { + return null; + } + DeclaredType declaredType = (DeclaredType) returnType; + TypeElement returnTypeElement = (TypeElement) declaredType.asElement(); + if ( !returnTypeElement.getQualifiedName().contentEquals( Boolean.class.getCanonicalName() ) ) { + return null; + } + } + + Set strategies = condition.appliesTo().get() + .stream() + .map( ConditionStrategyGem::valueOf ) + .collect( Collectors.toCollection( () -> EnumSet.noneOf( ConditionStrategyGem.class ) ) ); + + if ( strategies.isEmpty() ) { + messager.printMessage( + method, + condition.mirror(), + condition.appliesTo().getAnnotationValue(), + Message.CONDITION_MISSING_APPLIES_TO_STRATEGY + ); + + return null; + } + + boolean allStrategiesValid = true; + + for ( ConditionStrategyGem strategy : strategies ) { + boolean isStrategyValid = isValid( strategy, condition, method, parameters, messager ); + allStrategiesValid &= isStrategyValid; + } + + return allStrategiesValid ? new ConditionOptions( strategies ) : null; + } + + protected static boolean isValid(ConditionStrategyGem strategy, ConditionGem condition, + ExecutableElement method, List parameters, + FormattingMessager messager) { + if ( strategy == ConditionStrategyGem.SOURCE_PARAMETERS ) { + return hasValidStrategyForSourceProperties( condition, method, parameters, messager ); + } + else if ( strategy == ConditionStrategyGem.PROPERTIES ) { + return hasValidStrategyForProperties( condition, method, parameters, messager ); + } + else { + throw new IllegalStateException( "Invalid condition strategy: " + strategy ); + } + } + + protected static boolean hasValidStrategyForSourceProperties(ConditionGem condition, ExecutableElement method, + List parameters, + FormattingMessager messager) { + for ( Parameter parameter : parameters ) { + if ( parameter.isSourceParameter() ) { + // source parameter is a valid parameter for a source condition check + continue; + } + + if ( parameter.isMappingContext() ) { + // mapping context parameter is a valid parameter for a source condition check + continue; + } + + messager.printMessage( + method, + condition.mirror(), + Message.CONDITION_SOURCE_PARAMETERS_INVALID_PARAMETER, + parameter.describe() + ); + return false; + } + return true; + } + + protected static boolean hasValidStrategyForProperties(ConditionGem condition, ExecutableElement method, + List parameters, + FormattingMessager messager) { + for ( Parameter parameter : parameters ) { + if ( parameter.isSourceParameter() ) { + // source parameter is a valid parameter for a property condition check + continue; + } + + if ( parameter.isMappingContext() ) { + // mapping context parameter is a valid parameter for a property condition check + continue; + } + + if ( parameter.isTargetType() ) { + // target type parameter is a valid parameter for a property condition check + continue; + } + + if ( parameter.isMappingTarget() ) { + // mapping target parameter is a valid parameter for a property condition check + continue; + } + + if ( parameter.isSourcePropertyName() ) { + // source property name parameter is a valid parameter for a property condition check + continue; + } + + if ( parameter.isTargetPropertyName() ) { + // target property name parameter is a valid parameter for a property condition check + continue; + } + + messager.printMessage( + method, + condition.mirror(), + Message.CONDITION_PROPERTIES_INVALID_PARAMETER, + parameter + ); + return false; + } + return true; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java new file mode 100644 index 0000000000..d958272f9b --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DefaultOptions.java @@ -0,0 +1,186 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Collections; +import java.util.Set; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.ClassAccessibilityGem; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; +import org.mapstruct.ap.internal.gem.MapperGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; +import org.mapstruct.ap.internal.gem.SubclassExhaustiveStrategyGem; +import org.mapstruct.ap.internal.option.Options; +import org.mapstruct.ap.internal.util.ElementUtils; + +public class DefaultOptions extends DelegatingOptions { + + private final MapperGem mapper; + private final Options options; + + DefaultOptions(MapperGem mapper, Options options) { + super( null ); + this.mapper = mapper; + this.options = options; + } + + @Override + public String implementationName() { + return mapper.implementationName().getDefaultValue(); + } + + @Override + public String implementationPackage() { + return mapper.implementationPackage().getDefaultValue(); + } + + @Override + public Set uses() { + return Collections.emptySet(); + } + + @Override + public Set imports() { + return Collections.emptySet(); + } + + @Override + public ReportingPolicyGem unmappedTargetPolicy() { + ReportingPolicyGem unmappedTargetPolicy = options.getUnmappedTargetPolicy(); + if ( unmappedTargetPolicy != null ) { + return unmappedTargetPolicy; + } + return ReportingPolicyGem.valueOf( mapper.unmappedTargetPolicy().getDefaultValue() ); + } + + @Override + public ReportingPolicyGem unmappedSourcePolicy() { + ReportingPolicyGem unmappedSourcePolicy = options.getUnmappedSourcePolicy(); + if ( unmappedSourcePolicy != null ) { + return unmappedSourcePolicy; + } + return ReportingPolicyGem.valueOf( mapper.unmappedSourcePolicy().getDefaultValue() ); + } + + @Override + public ReportingPolicyGem typeConversionPolicy() { + return ReportingPolicyGem.valueOf( mapper.typeConversionPolicy().getDefaultValue() ); + } + + @Override + public String componentModel() { + String defaultComponentModel = options.getDefaultComponentModel(); + if ( defaultComponentModel != null ) { + return defaultComponentModel; + } + return mapper.componentModel().getDefaultValue(); + } + + public boolean suppressTimestampInGenerated() { + if ( mapper.suppressTimestampInGenerated().hasValue() ) { + return mapper.suppressTimestampInGenerated().getValue(); + } + return options.isSuppressGeneratorTimestamp(); + } + + @Override + public MappingInheritanceStrategyGem getMappingInheritanceStrategy() { + return MappingInheritanceStrategyGem.valueOf( mapper.mappingInheritanceStrategy().getDefaultValue() ); + } + + @Override + public InjectionStrategyGem getInjectionStrategy() { + String defaultInjectionStrategy = options.getDefaultInjectionStrategy(); + if ( defaultInjectionStrategy != null ) { + return InjectionStrategyGem.valueOf( defaultInjectionStrategy.toUpperCase() ); + } + return InjectionStrategyGem.valueOf( mapper.injectionStrategy().getDefaultValue() ); + } + + @Override + public Boolean isDisableSubMappingMethodsGeneration() { + return mapper.disableSubMappingMethodsGeneration().getDefaultValue(); + } + + // BeanMapping and Mapping + + public CollectionMappingStrategyGem getCollectionMappingStrategy() { + return CollectionMappingStrategyGem.valueOf( mapper.collectionMappingStrategy().getDefaultValue() ); + } + + public NullValueCheckStrategyGem getNullValueCheckStrategy() { + return NullValueCheckStrategyGem.valueOf( mapper.nullValueCheckStrategy().getDefaultValue() ); + } + + public NullValuePropertyMappingStrategyGem getNullValuePropertyMappingStrategy() { + return NullValuePropertyMappingStrategyGem.valueOf( + mapper.nullValuePropertyMappingStrategy().getDefaultValue() ); + } + + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return NullValueMappingStrategyGem.valueOf( mapper.nullValueMappingStrategy().getDefaultValue() ); + } + + public SubclassExhaustiveStrategyGem getSubclassExhaustiveStrategy() { + return SubclassExhaustiveStrategyGem.valueOf( mapper.subclassExhaustiveStrategy().getDefaultValue() ); + } + + public TypeMirror getSubclassExhaustiveException() { + return mapper.subclassExhaustiveException().getDefaultValue(); + } + + public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() { + NullValueMappingStrategyGem nullValueIterableMappingStrategy = options.getNullValueIterableMappingStrategy(); + if ( nullValueIterableMappingStrategy != null ) { + return nullValueIterableMappingStrategy; + } + return NullValueMappingStrategyGem.valueOf( mapper.nullValueIterableMappingStrategy().getDefaultValue() ); + } + + public NullValueMappingStrategyGem getNullValueMapMappingStrategy() { + NullValueMappingStrategyGem nullValueMapMappingStrategy = options.getNullValueMapMappingStrategy(); + if ( nullValueMapMappingStrategy != null ) { + return nullValueMapMappingStrategy; + } + return NullValueMappingStrategyGem.valueOf( mapper.nullValueMapMappingStrategy().getDefaultValue() ); + } + + @Override + public ClassAccessibilityGem accessibility() { + return ClassAccessibilityGem.valueOf( mapper.accessibility().getDefaultValue() ); + } + + public BuilderGem getBuilder() { + // TODO: I realized this is not correct, however it needs to be null in order to keep downward compatibility + // but assuming a default @Builder will make testcases fail. Not having a default means that you need to + // specify this mandatory on @MapperConfig and @Mapper. + return null; + } + + @Override + public MappingControl getMappingControl(ElementUtils elementUtils) { + return MappingControl.fromTypeMirror( mapper.mappingControl().getDefaultValue(), elementUtils ); + } + + @Override + public TypeMirror getUnexpectedValueMappingException() { + return null; + } + + @Override + public boolean hasAnnotation() { + return false; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java new file mode 100644 index 0000000000..e97f527745 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/DelegatingOptions.java @@ -0,0 +1,161 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.ClassAccessibilityGem; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; +import org.mapstruct.ap.internal.gem.SubclassExhaustiveStrategyGem; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.spi.TypeHierarchyErroneousException; + +/** + * Chain Of Responsibility Pattern. + */ +public abstract class DelegatingOptions { + + private final DelegatingOptions next; + + public DelegatingOptions(DelegatingOptions next) { + this.next = next; + } + + // @Mapper and @MapperConfig + + public String implementationName() { + return next.implementationName(); + } + + public String implementationPackage() { + return next.implementationPackage(); + } + + public Set uses() { + return next.uses(); + } + + public Set imports() { + return next.imports(); + } + + public ReportingPolicyGem unmappedTargetPolicy() { + return next.unmappedTargetPolicy(); + } + + public ReportingPolicyGem unmappedSourcePolicy() { + return next.unmappedSourcePolicy(); + } + + public ReportingPolicyGem typeConversionPolicy() { + return next.typeConversionPolicy(); + } + + public String componentModel() { + return next.componentModel(); + } + + public boolean suppressTimestampInGenerated() { + return next.suppressTimestampInGenerated(); + } + + public MappingInheritanceStrategyGem getMappingInheritanceStrategy() { + return next.getMappingInheritanceStrategy(); + } + + public InjectionStrategyGem getInjectionStrategy() { + return next.getInjectionStrategy(); + } + + public Boolean isDisableSubMappingMethodsGeneration() { + return next.isDisableSubMappingMethodsGeneration(); + } + + public ClassAccessibilityGem accessibility() { + return next.accessibility(); + } + + // BeanMapping and Mapping + + public CollectionMappingStrategyGem getCollectionMappingStrategy() { + return next.getCollectionMappingStrategy(); + } + + public NullValueCheckStrategyGem getNullValueCheckStrategy() { + return next.getNullValueCheckStrategy(); + } + + public NullValuePropertyMappingStrategyGem getNullValuePropertyMappingStrategy() { + return next.getNullValuePropertyMappingStrategy(); + } + + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return next.getNullValueMappingStrategy(); + } + + public SubclassExhaustiveStrategyGem getSubclassExhaustiveStrategy() { + return next.getSubclassExhaustiveStrategy(); + } + + public TypeMirror getSubclassExhaustiveException() { + return next.getSubclassExhaustiveException(); + } + + public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() { + return next.getNullValueIterableMappingStrategy(); + } + + public NullValueMappingStrategyGem getNullValueMapMappingStrategy() { + return next.getNullValueMapMappingStrategy(); + } + + public BuilderGem getBuilder() { + return next.getBuilder(); + } + + public MappingControl getMappingControl(ElementUtils elementUtils) { + return next.getMappingControl( elementUtils ); + } + + public TypeMirror getUnexpectedValueMappingException() { + return next.getUnexpectedValueMappingException(); + } + + DelegatingOptions next() { + return next; + } + + protected Set toDeclaredTypes(List in, Set next) { + Set result = new LinkedHashSet<>(); + for ( TypeMirror typeMirror : in ) { + if ( typeMirror == null ) { + // When a class used in uses or imports is created by another annotation processor + // then javac will not return correct TypeMirror with TypeKind#ERROR, but rather a string "" + // the gem tools would return a null TypeMirror in that case. + // Therefore throw TypeHierarchyErroneousException so we can postpone the generation of the mapper + throw new TypeHierarchyErroneousException( typeMirror ); + } + + result.add( (DeclaredType) typeMirror ); + } + result.addAll( next ); + return result; + } + + public abstract boolean hasAnnotation(); + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMapping.java deleted file mode 100644 index 62e681245b..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMapping.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -/** - * Represents the mapping between one enum constant and another. - * - * @author Gunnar Morling - */ -public class EnumMapping { - - private final String source; - private final String target; - - public EnumMapping(String source, String target) { - this.source = source; - this.target = target; - } - - /** - * @return the name of the constant in the source enum. - */ - public String getSource() { - return source; - } - - /** - * @return the name of the constant in the target enum. - */ - public String getTarget() { - return target; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java new file mode 100644 index 0000000000..41b74aa13a --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/EnumMappingOptions.java @@ -0,0 +1,149 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Map; +import java.util.Optional; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.EnumMappingGem; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.spi.EnumTransformationStrategy; + +import static org.mapstruct.ap.internal.util.Message.ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY; +import static org.mapstruct.ap.internal.util.Message.ENUMMAPPING_MISSING_CONFIGURATION; +import static org.mapstruct.ap.internal.util.Message.ENUMMAPPING_NO_ELEMENTS; + +/** + * Represents an enum mapping as configured via {@code @EnumMapping}. + * + * @author Filip Hrisafov + */ +public class EnumMappingOptions extends DelegatingOptions { + + private final EnumMappingGem enumMapping; + private final boolean inverse; + private final boolean valid; + + private EnumMappingOptions(EnumMappingGem enumMapping, boolean inverse, boolean valid, DelegatingOptions next) { + super( next ); + this.enumMapping = enumMapping; + this.inverse = inverse; + this.valid = valid; + } + + @Override + public boolean hasAnnotation() { + return enumMapping != null; + } + + public boolean isValid() { + return valid; + } + + public boolean hasNameTransformationStrategy() { + return hasAnnotation() && Strings.isNotEmpty( getNameTransformationStrategy() ); + } + + public String getNameTransformationStrategy() { + return enumMapping.nameTransformationStrategy().getValue(); + } + + public String getNameTransformationConfiguration() { + return enumMapping.configuration().getValue(); + } + + @Override + public TypeMirror getUnexpectedValueMappingException() { + if ( enumMapping != null && enumMapping.unexpectedValueMappingException().hasValue() ) { + return enumMapping.unexpectedValueMappingException().getValue(); + } + + return next().getUnexpectedValueMappingException(); + } + + public AnnotationMirror getMirror() { + return Optional.ofNullable( enumMapping ).map( EnumMappingGem::mirror ).orElse( null ); + } + + public boolean isInverse() { + return inverse; + } + + public EnumMappingOptions inverse() { + return new EnumMappingOptions( enumMapping, true, valid, next() ); + } + + public static EnumMappingOptions getInstanceOn(ExecutableElement method, MapperOptions mapperOptions, + Map enumTransformationStrategies, FormattingMessager messager) { + + EnumMappingGem enumMapping = EnumMappingGem.instanceOn( method ); + if ( enumMapping == null ) { + return new EnumMappingOptions( null, false, true, mapperOptions ); + } + else if ( !isConsistent( enumMapping, method, enumTransformationStrategies, messager ) ) { + return new EnumMappingOptions( null, false, false, mapperOptions ); + } + + return new EnumMappingOptions( + enumMapping, + false, + true, + mapperOptions + ); + } + + private static boolean isConsistent(EnumMappingGem gem, ExecutableElement method, + Map enumTransformationStrategies, FormattingMessager messager) { + + String strategy = gem.nameTransformationStrategy().getValue(); + String configuration = gem.configuration().getValue(); + + boolean isConsistent = false; + + if ( Strings.isNotEmpty( strategy ) || Strings.isNotEmpty( configuration ) ) { + if ( !enumTransformationStrategies.containsKey( strategy ) ) { + String registeredStrategies = Strings.join( enumTransformationStrategies.keySet(), ", " ); + messager.printMessage( + method, + gem.mirror(), + gem.nameTransformationStrategy().getAnnotationValue(), + ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY, + strategy, + registeredStrategies + ); + + return false; + } + else if ( Strings.isEmpty( configuration ) ) { + messager.printMessage( + method, + gem.mirror(), + gem.configuration().getAnnotationValue(), + ENUMMAPPING_MISSING_CONFIGURATION + ); + return false; + } + + isConsistent = true; + } + + isConsistent = isConsistent || gem.unexpectedValueMappingException().hasValue(); + + if ( !isConsistent ) { + messager.printMessage( + method, + gem.mirror(), + ENUMMAPPING_NO_ELEMENTS + ); + } + + return isConsistent; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ForgedMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ForgedMethod.java deleted file mode 100644 index 97523a2a60..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ForgedMethod.java +++ /dev/null @@ -1,348 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.lang.model.element.ExecutableElement; - -import org.mapstruct.ap.internal.model.common.Accessibility; -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.util.MapperConfiguration; -import org.mapstruct.ap.internal.util.Strings; - -/** - * This method will be generated in absence of a suitable abstract method to implement. - * - * @author Sjaak Derksen - */ -public class ForgedMethod implements Method { - - private final List parameters; - private final Type returnType; - private final String name; - private final ExecutableElement positionHintElement; - private final List thrownTypes; - private final MapperConfiguration mapperConfiguration; - private final ForgedMethodHistory history; - - private final List sourceParameters; - private final List contextParameters; - private final Parameter mappingTargetParameter; - private final MappingOptions mappingOptions; - private final ParameterProvidedMethods contextProvidedMethods; - private final boolean forgedNameBased; - - /** - * Creates a new forged method with the given name. - * - * @param name the (unique name) for this method - * @param sourceType the source type - * @param returnType the return type. - * @param mapperConfiguration the mapper configuration - * @param positionHintElement element used to for reference to the position in the source file. - * @param additionalParameters additional parameters to add to the forged method - * @param parameterProvidedMethods additional factory/lifecycle methods to consider that are provided by context - * parameters - */ - public ForgedMethod(String name, Type sourceType, Type returnType, MapperConfiguration mapperConfiguration, - ExecutableElement positionHintElement, List additionalParameters, - ParameterProvidedMethods parameterProvidedMethods) { - this( - name, - sourceType, - returnType, - mapperConfiguration, - positionHintElement, - additionalParameters, - parameterProvidedMethods, - null, - null, - false ); - } - - /** - * Creates a new forged method with the given name. - * - * @param name the (unique name) for this method - * @param sourceType the source type - * @param returnType the return type. - * @param mapperConfiguration the mapper configuration - * @param positionHintElement element used to for reference to the position in the source file. - * @param additionalParameters additional parameters to add to the forged method - * @param parameterProvidedMethods additional factory/lifecycle methods to consider that are provided by context - * parameters - * @param history a parent forged method if this is a forged method within a forged method - * @param mappingOptions the mapping options for this method - * @param forgedNameBased forges a name based (matched) mapping method - */ - public ForgedMethod(String name, Type sourceType, Type returnType, MapperConfiguration mapperConfiguration, - ExecutableElement positionHintElement, List additionalParameters, - ParameterProvidedMethods parameterProvidedMethods, ForgedMethodHistory history, - MappingOptions mappingOptions, boolean forgedNameBased) { - String sourceParamName = Strings.decapitalize( sourceType.getName() ); - String sourceParamSafeName = Strings.getSaveVariableName( sourceParamName ); - - this.parameters = new ArrayList( 1 + additionalParameters.size() ); - Parameter sourceParameter = new Parameter( sourceParamSafeName, sourceType ); - this.parameters.add( sourceParameter ); - this.parameters.addAll( additionalParameters ); - this.sourceParameters = Parameter.getSourceParameters( parameters ); - this.contextParameters = Parameter.getContextParameters( parameters ); - this.mappingTargetParameter = Parameter.getMappingTargetParameter( parameters ); - this.contextProvidedMethods = parameterProvidedMethods; - - this.returnType = returnType; - this.thrownTypes = new ArrayList(); - this.name = Strings.sanitizeIdentifierName( name ); - this.mapperConfiguration = mapperConfiguration; - this.positionHintElement = positionHintElement; - this.history = history; - this.mappingOptions = mappingOptions == null ? MappingOptions.empty() : mappingOptions; - this.mappingOptions.initWithParameter( sourceParameter ); - this.forgedNameBased = forgedNameBased; - } - - /** - * creates a new ForgedMethod with the same arguments but with a new name - * @param name the new name - * @param forgedMethod existing forge method - */ - public ForgedMethod(String name, ForgedMethod forgedMethod) { - this.parameters = forgedMethod.parameters; - this.returnType = forgedMethod.returnType; - this.thrownTypes = new ArrayList(); - this.mapperConfiguration = forgedMethod.mapperConfiguration; - this.positionHintElement = forgedMethod.positionHintElement; - this.history = forgedMethod.history; - - this.sourceParameters = Parameter.getSourceParameters( parameters ); - this.contextParameters = Parameter.getContextParameters( parameters ); - this.mappingTargetParameter = Parameter.getMappingTargetParameter( parameters ); - this.mappingOptions = forgedMethod.mappingOptions; - this.contextProvidedMethods = forgedMethod.contextProvidedMethods; - - this.name = name; - this.forgedNameBased = forgedMethod.forgedNameBased; - } - - @Override - public boolean matches(List sourceTypes, Type targetType) { - - if ( !targetType.equals( returnType ) ) { - return false; - } - - if ( parameters.size() != sourceTypes.size() ) { - return false; - } - - Iterator srcTypeIt = sourceTypes.iterator(); - Iterator paramIt = parameters.iterator(); - - while ( srcTypeIt.hasNext() && paramIt.hasNext() ) { - Type sourceType = srcTypeIt.next(); - Parameter param = paramIt.next(); - if ( !sourceType.equals( param.getType() ) ) { - return false; - } - } - - return true; - } - - @Override - public Type getDeclaringMapper() { - return null; - } - - @Override - public String getName() { - return name; - } - - @Override - public List getParameters() { - return parameters; - } - - @Override - public List getSourceParameters() { - return sourceParameters; - } - - @Override - public List getContextParameters() { - return contextParameters; - } - - @Override - public ParameterProvidedMethods getContextProvidedMethods() { - return contextProvidedMethods; - } - - @Override - public Parameter getMappingTargetParameter() { - return mappingTargetParameter; - } - - @Override - public Parameter getTargetTypeParameter() { - return null; - } - - @Override - public Accessibility getAccessibility() { - return Accessibility.PROTECTED; - } - - @Override - public Type getReturnType() { - return returnType; - } - - @Override - public List getThrownTypes() { - return thrownTypes; - } - - public ForgedMethodHistory getHistory() { - return history; - } - - public boolean isForgedNamedBased() { - return forgedNameBased; - } - - public void addThrownTypes(List thrownTypesToAdd) { - for ( Type thrownType : thrownTypesToAdd ) { - // make sure there are no duplicates coming from the keyAssignment thrown types. - if ( !thrownTypes.contains( thrownType ) ) { - thrownTypes.add( thrownType ); - } - } - } - - @Override - public Type getResultType() { - return mappingTargetParameter != null ? mappingTargetParameter.getType() : returnType; - } - - @Override - public List getParameterNames() { - List parameterNames = new ArrayList(); - for ( Parameter parameter : getParameters() ) { - parameterNames.add( parameter.getName() ); - } - return parameterNames; - } - - @Override - public boolean overridesMethod() { - return false; - } - - @Override - public ExecutableElement getExecutable() { - return positionHintElement; - } - - @Override - public boolean isLifecycleCallbackMethod() { - return false; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder( returnType.toString() ); - sb.append( " " ); - - sb.append( getName() ).append( "(" ).append( Strings.join( parameters, ", " ) ).append( ")" ); - - return sb.toString(); - } - - @Override - public boolean isStatic() { - return false; - } - - @Override - public boolean isDefault() { - return false; - } - - @Override - public Type getDefiningType() { - return null; - } - - @Override - public MapperConfiguration getMapperConfiguration() { - return mapperConfiguration; - } - - @Override - public boolean isUpdateMethod() { - return getMappingTargetParameter() != null; - } - - /** - * object factory mechanism not supported for forged methods - * - * @return false - */ - @Override - public boolean isObjectFactory() { - return false; - } - - @Override - public MappingOptions getMappingOptions() { - return mappingOptions; - } - - @Override - public boolean equals(Object o) { - if ( this == o ) { - return true; - } - if ( o == null || getClass() != o.getClass() ) { - return false; - } - - ForgedMethod that = (ForgedMethod) o; - - if ( parameters != null ? !parameters.equals( that.parameters ) : that.parameters != null ) { - return false; - } - return returnType != null ? returnType.equals( that.returnType ) : that.returnType == null; - - } - - @Override - public int hashCode() { - int result = parameters != null ? parameters.hashCode() : 0; - result = 31 * result + ( returnType != null ? returnType.hashCode() : 0 ); - return result; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/IterableMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/IterableMapping.java deleted file mode 100644 index 8e96790a22..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/IterableMapping.java +++ /dev/null @@ -1,113 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.type.TypeKind; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.model.common.FormattingParameters; -import org.mapstruct.ap.internal.prism.IterableMappingPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; - -/** - * Represents an iterable mapping as configured via {@code @IterableMapping}. - * - * @author Gunnar Morling - */ -public class IterableMapping { - - private final SelectionParameters selectionParameters; - private final FormattingParameters formattingParameters; - private final AnnotationMirror mirror; - private final NullValueMappingStrategyPrism nullValueMappingStrategy; - - public static IterableMapping fromPrism(IterableMappingPrism iterableMapping, ExecutableElement method, - FormattingMessager messager, Types typeUtils) { - if ( iterableMapping == null ) { - return null; - } - - boolean elementTargetTypeIsDefined = !TypeKind.VOID.equals( iterableMapping.elementTargetType().getKind() ); - - NullValueMappingStrategyPrism nullValueMappingStrategy = - iterableMapping.values.nullValueMappingStrategy() == null - ? null - : NullValueMappingStrategyPrism.valueOf( iterableMapping.nullValueMappingStrategy() ); - - if ( !elementTargetTypeIsDefined - && iterableMapping.dateFormat().isEmpty() - && iterableMapping.numberFormat().isEmpty() - && iterableMapping.qualifiedBy().isEmpty() - && iterableMapping.qualifiedByName().isEmpty() - && ( nullValueMappingStrategy == null ) ) { - - messager.printMessage( method, Message.ITERABLEMAPPING_NO_ELEMENTS ); - } - - SelectionParameters selection = new SelectionParameters( - iterableMapping.qualifiedBy(), - iterableMapping.qualifiedByName(), - elementTargetTypeIsDefined ? iterableMapping.elementTargetType() : null, - typeUtils - ); - - FormattingParameters formatting = new FormattingParameters( - iterableMapping.dateFormat(), - iterableMapping.numberFormat(), - iterableMapping.mirror, - iterableMapping.values.dateFormat(), - method - ); - - return new IterableMapping( formatting, - selection, - iterableMapping.mirror, - nullValueMappingStrategy - ); - } - - private IterableMapping(FormattingParameters formattingParameters, SelectionParameters selectionParameters, - AnnotationMirror mirror, NullValueMappingStrategyPrism nvms) { - - this.formattingParameters = formattingParameters; - this.selectionParameters = selectionParameters; - this.mirror = mirror; - this.nullValueMappingStrategy = nvms; - } - - public SelectionParameters getSelectionParameters() { - return selectionParameters; - } - - public FormattingParameters getFormattingParameters() { - return formattingParameters; - } - - public AnnotationMirror getMirror() { - return mirror; - } - - public NullValueMappingStrategyPrism getNullValueMappingStrategy() { - return nullValueMappingStrategy; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/IterableMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/IterableMappingOptions.java new file mode 100644 index 0000000000..50fca3e4d2 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/IterableMappingOptions.java @@ -0,0 +1,124 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Optional; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.ExecutableElement; + +import org.mapstruct.ap.internal.gem.IterableMappingGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.model.common.FormattingParameters; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.tools.gem.GemValue; + +/** + * Represents an iterable mapping as configured via {@code @IterableMapping}. + * + * @author Gunnar Morling + */ +public class IterableMappingOptions extends DelegatingOptions { + + private final SelectionParameters selectionParameters; + private final FormattingParameters formattingParameters; + private final IterableMappingGem iterableMapping; + + public static IterableMappingOptions fromGem(IterableMappingGem iterableMapping, + MapperOptions mapperOptions, ExecutableElement method, + FormattingMessager messager, TypeUtils typeUtils) { + + if ( iterableMapping == null || !isConsistent( iterableMapping, method, messager ) ) { + IterableMappingOptions options = new IterableMappingOptions( + null, + SelectionParameters.empty(), + null, + mapperOptions + ); + return options; + } + + SelectionParameters selection = new SelectionParameters( + iterableMapping.qualifiedBy().get(), + iterableMapping.qualifiedByName().get(), + iterableMapping.elementTargetType().getValue(), + typeUtils + ); + + FormattingParameters formatting = new FormattingParameters( + iterableMapping.dateFormat().get(), + iterableMapping.numberFormat().get(), + iterableMapping.mirror(), + iterableMapping.dateFormat().getAnnotationValue(), + method, + iterableMapping.locale().getValue() + ); + + IterableMappingOptions options = + new IterableMappingOptions( formatting, selection, iterableMapping, mapperOptions ); + return options; + } + + private static boolean isConsistent(IterableMappingGem gem, ExecutableElement method, + FormattingMessager messager) { + if ( !gem.dateFormat().hasValue() + && !gem.numberFormat().hasValue() + && !gem.qualifiedBy().hasValue() + && !gem.qualifiedByName().hasValue() + && !gem.elementTargetType().hasValue() + && !gem.nullValueMappingStrategy().hasValue() ) { + messager.printMessage( method, Message.ITERABLEMAPPING_NO_ELEMENTS ); + return false; + } + return true; + } + + private IterableMappingOptions(FormattingParameters formattingParameters, SelectionParameters selectionParameters, + IterableMappingGem iterableMapping, + DelegatingOptions next) { + super( next ); + this.formattingParameters = formattingParameters; + this.selectionParameters = selectionParameters; + this.iterableMapping = iterableMapping; + } + + public SelectionParameters getSelectionParameters() { + return selectionParameters; + } + + public FormattingParameters getFormattingParameters() { + return formattingParameters; + } + + public AnnotationMirror getMirror() { + return Optional.ofNullable( iterableMapping ).map( IterableMappingGem::mirror ).orElse( null ); + } + + @Override + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return Optional.ofNullable( iterableMapping ).map( IterableMappingGem::nullValueMappingStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValueMappingStrategyGem::valueOf ) + .orElse( next().getNullValueIterableMappingStrategy() ); + } + + public MappingControl getElementMappingControl(ElementUtils elementUtils) { + return Optional.ofNullable( iterableMapping ).map( IterableMappingGem::elementMappingControl ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( mc -> MappingControl.fromTypeMirror( mc, elementUtils ) ) + .orElse( next().getMappingControl( elementUtils ) ); + } + + @Override + public boolean hasAnnotation() { + return iterableMapping != null; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapMapping.java deleted file mode 100644 index adeac692c7..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapMapping.java +++ /dev/null @@ -1,150 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.type.TypeKind; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.model.common.FormattingParameters; -import org.mapstruct.ap.internal.prism.MapMappingPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; - -/** - * Represents a map mapping as configured via {@code @MapMapping}. - * - * @author Gunnar Morling - */ -public class MapMapping { - - private final SelectionParameters keySelectionParameters; - private final SelectionParameters valueSelectionParameters; - private final FormattingParameters keyFormattingParameters; - private final FormattingParameters valueFormattingParameters; - private final AnnotationMirror mirror; - private final NullValueMappingStrategyPrism nullValueMappingStrategy; - - public static MapMapping fromPrism(MapMappingPrism mapMapping, ExecutableElement method, - FormattingMessager messager, Types typeUtils) { - if ( mapMapping == null ) { - return null; - } - - NullValueMappingStrategyPrism nullValueMappingStrategy = - mapMapping.values.nullValueMappingStrategy() == null - ? null - : NullValueMappingStrategyPrism.valueOf( mapMapping.nullValueMappingStrategy() ); - - - boolean keyTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.keyTargetType().getKind() ); - boolean valueTargetTypeIsDefined = !TypeKind.VOID.equals( mapMapping.valueTargetType().getKind() ); - if ( mapMapping.keyDateFormat().isEmpty() - && mapMapping.keyNumberFormat().isEmpty() - && mapMapping.keyQualifiedBy().isEmpty() - && mapMapping.keyQualifiedByName().isEmpty() - && mapMapping.valueDateFormat().isEmpty() - && mapMapping.valueNumberFormat().isEmpty() - && mapMapping.valueQualifiedBy().isEmpty() - && mapMapping.valueQualifiedByName().isEmpty() - && !keyTargetTypeIsDefined - && !valueTargetTypeIsDefined - && ( nullValueMappingStrategy == null ) ) { - - messager.printMessage( method, Message.MAPMAPPING_NO_ELEMENTS ); - } - - SelectionParameters keySelection = new SelectionParameters( - mapMapping.keyQualifiedBy(), - mapMapping.keyQualifiedByName(), - keyTargetTypeIsDefined ? mapMapping.keyTargetType() : null, - typeUtils - ); - - SelectionParameters valueSelection = new SelectionParameters( - mapMapping.valueQualifiedBy(), - mapMapping.valueQualifiedByName(), - valueTargetTypeIsDefined ? mapMapping.valueTargetType() : null, - typeUtils - ); - - FormattingParameters keyFormatting = new FormattingParameters( - mapMapping.keyDateFormat(), - mapMapping.keyNumberFormat(), - mapMapping.mirror, - mapMapping.values.keyDateFormat(), - method - ); - - FormattingParameters valueFormatting = new FormattingParameters( - mapMapping.valueDateFormat(), - mapMapping.valueNumberFormat(), - mapMapping.mirror, - mapMapping.values.valueDateFormat(), - method - ); - - return new MapMapping( - keyFormatting, - keySelection, - valueFormatting, - valueSelection, - mapMapping.mirror, - nullValueMappingStrategy - ); - } - - private MapMapping(FormattingParameters keyFormatting, SelectionParameters keySelectionParameters, - FormattingParameters valueFormatting, SelectionParameters valueSelectionParameters, AnnotationMirror mirror, - NullValueMappingStrategyPrism nvms ) { - this.keyFormattingParameters = keyFormatting; - this.keySelectionParameters = keySelectionParameters; - this.valueFormattingParameters = valueFormatting; - this.valueSelectionParameters = valueSelectionParameters; - this.mirror = mirror; - this.nullValueMappingStrategy = nvms; - } - - public FormattingParameters getKeyFormattingParameters() { - return keyFormattingParameters; - } - - public SelectionParameters getKeySelectionParameters() { - return keySelectionParameters; - } - - public FormattingParameters getValueFormattingParameters() { - return valueFormattingParameters; - } - - public SelectionParameters getValueSelectionParameters() { - return valueSelectionParameters; - } - - public AnnotationMirror getMirror() { - return mirror; - } - - public NullValueMappingStrategyPrism getNullValueMappingStrategy() { - return nullValueMappingStrategy; - } - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapMappingOptions.java new file mode 100644 index 0000000000..9f3d12faf3 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapMappingOptions.java @@ -0,0 +1,175 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Optional; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.ExecutableElement; + +import org.mapstruct.ap.internal.gem.MapMappingGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.model.common.FormattingParameters; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.tools.gem.GemValue; + +/** + * Represents a map mapping as configured via {@code @MapMapping}. + * + * @author Gunnar Morling + */ +public class MapMappingOptions extends DelegatingOptions { + + private final SelectionParameters keySelectionParameters; + private final SelectionParameters valueSelectionParameters; + private final FormattingParameters keyFormattingParameters; + private final FormattingParameters valueFormattingParameters; + private final MapMappingGem mapMapping; + + public static MapMappingOptions fromGem(MapMappingGem mapMapping, MapperOptions mapperOptions, + ExecutableElement method, FormattingMessager messager, + TypeUtils typeUtils) { + + if ( mapMapping == null || !isConsistent( mapMapping, method, messager ) ) { + MapMappingOptions options = new MapMappingOptions( + null, + SelectionParameters.empty(), + null, + SelectionParameters.empty(), + null, + mapperOptions + ); + return options; + } + + String locale = mapMapping.locale().getValue(); + + SelectionParameters keySelection = new SelectionParameters( + mapMapping.keyQualifiedBy().get(), + mapMapping.keyQualifiedByName().get(), + mapMapping.keyTargetType().getValue(), + typeUtils + ); + + SelectionParameters valueSelection = new SelectionParameters( + mapMapping.valueQualifiedBy().get(), + mapMapping.valueQualifiedByName().get(), + mapMapping.valueTargetType().getValue(), + typeUtils + ); + + FormattingParameters keyFormatting = new FormattingParameters( + mapMapping.keyDateFormat().get(), + mapMapping.keyNumberFormat().get(), + mapMapping.mirror(), + mapMapping.keyDateFormat().getAnnotationValue(), + method, + locale + ); + + FormattingParameters valueFormatting = new FormattingParameters( + mapMapping.valueDateFormat().get(), + mapMapping.valueNumberFormat().get(), + mapMapping.mirror(), + mapMapping.valueDateFormat().getAnnotationValue(), + method, + locale + ); + + MapMappingOptions options = new MapMappingOptions( + keyFormatting, + keySelection, + valueFormatting, + valueSelection, + mapMapping, + mapperOptions + ); + return options; + } + + private static boolean isConsistent(MapMappingGem gem, ExecutableElement method, + FormattingMessager messager) { + if ( !gem.keyDateFormat().hasValue() + && !gem.keyNumberFormat().hasValue() + && !gem.keyQualifiedBy().hasValue() + && !gem.keyQualifiedByName().hasValue() + && !gem.valueDateFormat().hasValue() + && !gem.valueNumberFormat().hasValue() + && !gem.valueQualifiedBy().hasValue() + && !gem.valueQualifiedByName().hasValue() + && !gem.keyTargetType().hasValue() + && !gem.valueTargetType().hasValue() + && !gem.nullValueMappingStrategy().hasValue() ) { + messager.printMessage( method, Message.MAPMAPPING_NO_ELEMENTS ); + return false; + } + return true; + } + + private MapMappingOptions(FormattingParameters keyFormatting, SelectionParameters keySelectionParameters, + FormattingParameters valueFormatting, SelectionParameters valueSelectionParameters, + MapMappingGem mapMapping, DelegatingOptions next ) { + super( next ); + this.keyFormattingParameters = keyFormatting; + this.keySelectionParameters = keySelectionParameters; + this.valueFormattingParameters = valueFormatting; + this.valueSelectionParameters = valueSelectionParameters; + this.mapMapping = mapMapping; + } + + public FormattingParameters getKeyFormattingParameters() { + return keyFormattingParameters; + } + + public SelectionParameters getKeySelectionParameters() { + return keySelectionParameters; + } + + public FormattingParameters getValueFormattingParameters() { + return valueFormattingParameters; + } + + public SelectionParameters getValueSelectionParameters() { + return valueSelectionParameters; + } + + public AnnotationMirror getMirror() { + return Optional.ofNullable( mapMapping ).map( MapMappingGem::mirror ).orElse( null ); + } + + @Override + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return Optional.ofNullable( mapMapping ).map( MapMappingGem::nullValueMappingStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValueMappingStrategyGem::valueOf ) + .orElse( next().getNullValueMapMappingStrategy() ); + } + + public MappingControl getKeyMappingControl(ElementUtils elementUtils) { + return Optional.ofNullable( mapMapping ).map( MapMappingGem::keyMappingControl ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( mc -> MappingControl.fromTypeMirror( mc, elementUtils ) ) + .orElse( next().getMappingControl( elementUtils ) ); + } + + public MappingControl getValueMappingControl(ElementUtils elementUtils) { + return Optional.ofNullable( mapMapping ).map( MapMappingGem::valueMappingControl ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( mc -> MappingControl.fromTypeMirror( mc, elementUtils ) ) + .orElse( next().getMappingControl( elementUtils ) ); + } + + @Override + public boolean hasAnnotation() { + return mapMapping != null; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java new file mode 100644 index 0000000000..b51008b713 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperConfigOptions.java @@ -0,0 +1,204 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Set; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.ClassAccessibilityGem; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; +import org.mapstruct.ap.internal.gem.MapperConfigGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; +import org.mapstruct.ap.internal.gem.SubclassExhaustiveStrategyGem; +import org.mapstruct.ap.internal.util.ElementUtils; + +public class MapperConfigOptions extends DelegatingOptions { + + private final MapperConfigGem mapperConfig; + + MapperConfigOptions(MapperConfigGem mapperConfig, DelegatingOptions next ) { + super( next ); + this.mapperConfig = mapperConfig; + } + + @Override + public String implementationName() { + return mapperConfig.implementationName().hasValue() ? mapperConfig.implementationName().get() : + next().implementationName(); + } + + @Override + public String implementationPackage() { + return mapperConfig.implementationPackage().hasValue() ? mapperConfig.implementationPackage().get() : + next().implementationPackage(); + } + + @Override + public Set uses() { + return toDeclaredTypes( mapperConfig.uses().get(), next().uses() ); + } + + @Override + public Set imports() { + return toDeclaredTypes( mapperConfig.imports().get(), next().imports() ); + } + + @Override + public ReportingPolicyGem unmappedTargetPolicy() { + return mapperConfig.unmappedTargetPolicy().hasValue() ? + ReportingPolicyGem.valueOf( mapperConfig.unmappedTargetPolicy().get() ) : next().unmappedTargetPolicy(); + + } + + @Override + public ReportingPolicyGem unmappedSourcePolicy() { + return mapperConfig.unmappedSourcePolicy().hasValue() ? + ReportingPolicyGem.valueOf( mapperConfig.unmappedSourcePolicy().get() ) : next().unmappedSourcePolicy(); + } + + @Override + public ReportingPolicyGem typeConversionPolicy() { + return mapperConfig.typeConversionPolicy().hasValue() ? + ReportingPolicyGem.valueOf( mapperConfig.typeConversionPolicy().get() ) : next().typeConversionPolicy(); + } + + @Override + public String componentModel() { + return mapperConfig.componentModel().hasValue() ? mapperConfig.componentModel().get() : next().componentModel(); + } + + @Override + public boolean suppressTimestampInGenerated() { + return mapperConfig.suppressTimestampInGenerated().hasValue() ? + mapperConfig.suppressTimestampInGenerated().get() : + next().suppressTimestampInGenerated(); + } + + @Override + public MappingInheritanceStrategyGem getMappingInheritanceStrategy() { + return mapperConfig.mappingInheritanceStrategy().hasValue() ? + MappingInheritanceStrategyGem.valueOf( mapperConfig.mappingInheritanceStrategy().get() ) : + next().getMappingInheritanceStrategy(); + } + + @Override + public InjectionStrategyGem getInjectionStrategy() { + return mapperConfig.injectionStrategy().hasValue() ? + InjectionStrategyGem.valueOf( mapperConfig.injectionStrategy().get() ) : + next().getInjectionStrategy(); + } + + @Override + public Boolean isDisableSubMappingMethodsGeneration() { + return mapperConfig.disableSubMappingMethodsGeneration().hasValue() ? + mapperConfig.disableSubMappingMethodsGeneration().get() : + next().isDisableSubMappingMethodsGeneration(); + } + + // @Mapping, @BeanMapping + + @Override + public CollectionMappingStrategyGem getCollectionMappingStrategy() { + return mapperConfig.collectionMappingStrategy().hasValue() ? + CollectionMappingStrategyGem.valueOf( mapperConfig.collectionMappingStrategy().get() ) : + next().getCollectionMappingStrategy(); + } + + @Override + public NullValueCheckStrategyGem getNullValueCheckStrategy() { + return mapperConfig.nullValueCheckStrategy().hasValue() ? + NullValueCheckStrategyGem.valueOf( mapperConfig.nullValueCheckStrategy().get() ) : + next().getNullValueCheckStrategy(); + } + + @Override + public NullValuePropertyMappingStrategyGem getNullValuePropertyMappingStrategy() { + return mapperConfig.nullValuePropertyMappingStrategy().hasValue() ? + NullValuePropertyMappingStrategyGem.valueOf( mapperConfig.nullValuePropertyMappingStrategy().get() ) : + next().getNullValuePropertyMappingStrategy(); + } + + @Override + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return mapperConfig.nullValueMappingStrategy().hasValue() ? + NullValueMappingStrategyGem.valueOf( mapperConfig.nullValueMappingStrategy().get() ) : + next().getNullValueMappingStrategy(); + } + + @Override + public SubclassExhaustiveStrategyGem getSubclassExhaustiveStrategy() { + return mapperConfig.subclassExhaustiveStrategy().hasValue() ? + SubclassExhaustiveStrategyGem.valueOf( mapperConfig.subclassExhaustiveStrategy().get() ) : + next().getSubclassExhaustiveStrategy(); + } + + public TypeMirror getSubclassExhaustiveException() { + return mapperConfig.subclassExhaustiveException().hasValue() ? + mapperConfig.subclassExhaustiveException().get() : + next().getSubclassExhaustiveException(); + } + + @Override + public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() { + if ( mapperConfig.nullValueIterableMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapperConfig.nullValueIterableMappingStrategy().get() ); + } + if ( mapperConfig.nullValueMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapperConfig.nullValueMappingStrategy().get() ); + } + return next().getNullValueIterableMappingStrategy(); + } + + @Override + public NullValueMappingStrategyGem getNullValueMapMappingStrategy() { + if ( mapperConfig.nullValueMapMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapperConfig.nullValueMapMappingStrategy().get() ); + } + if ( mapperConfig.nullValueMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapperConfig.nullValueMappingStrategy().get() ); + } + return next().getNullValueMapMappingStrategy(); + } + + @Override + public ClassAccessibilityGem accessibility() { + return mapperConfig.accessibility().hasValue() ? + ClassAccessibilityGem.valueOf( mapperConfig.accessibility().get() ) : + next().accessibility(); + } + + @Override + public BuilderGem getBuilder() { + return mapperConfig.builder().hasValue() ? mapperConfig.builder().get() : next().getBuilder(); + } + + @Override + public MappingControl getMappingControl(ElementUtils elementUtils) { + return mapperConfig.mappingControl().hasValue() ? + MappingControl.fromTypeMirror( mapperConfig.mappingControl().getValue(), elementUtils ) : + next().getMappingControl( elementUtils ); + } + + @Override + public TypeMirror getUnexpectedValueMappingException() { + return mapperConfig.unexpectedValueMappingException().hasValue() ? + mapperConfig.unexpectedValueMappingException().get() : + next().getUnexpectedValueMappingException(); + } + + @Override + public boolean hasAnnotation() { + return mapperConfig != null; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java new file mode 100644 index 0000000000..b30b8c95fa --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MapperOptions.java @@ -0,0 +1,252 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.BuilderGem; +import org.mapstruct.ap.internal.gem.ClassAccessibilityGem; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; +import org.mapstruct.ap.internal.gem.MapperConfigGem; +import org.mapstruct.ap.internal.gem.MapperGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; +import org.mapstruct.ap.internal.gem.SubclassExhaustiveStrategyGem; +import org.mapstruct.ap.internal.option.Options; +import org.mapstruct.ap.internal.util.ElementUtils; + +public class MapperOptions extends DelegatingOptions { + + private final MapperGem mapper; + private final DeclaredType mapperConfigType; + + public static MapperOptions getInstanceOn(TypeElement typeElement, Options options) { + MapperGem mapper = MapperGem.instanceOn( typeElement ); + MapperOptions mapperAnnotation; + DelegatingOptions defaults = new DefaultOptions( mapper, options ); + DeclaredType mapperConfigType; + if ( mapper.config().hasValue() && mapper.config().getValue().getKind() == TypeKind.DECLARED ) { + mapperConfigType = (DeclaredType) mapper.config().get(); + } + else { + mapperConfigType = null; + } + if ( mapperConfigType != null ) { + Element mapperConfigElement = mapperConfigType.asElement(); + MapperConfigGem mapperConfig = MapperConfigGem.instanceOn( mapperConfigElement ); + MapperConfigOptions mapperConfigAnnotation = new MapperConfigOptions( mapperConfig, defaults ); + mapperAnnotation = new MapperOptions( mapper, mapperConfigType, mapperConfigAnnotation ); + } + else { + mapperAnnotation = new MapperOptions( mapper, null, defaults ); + } + return mapperAnnotation; + } + + private MapperOptions(MapperGem mapper, DeclaredType mapperConfigType, DelegatingOptions next) { + super( next ); + this.mapper = mapper; + this.mapperConfigType = mapperConfigType; + } + + @Override + public String implementationName() { + return mapper.implementationName().hasValue() ? mapper.implementationName().get() : next().implementationName(); + } + + @Override + public String implementationPackage() { + return mapper.implementationPackage().hasValue() ? mapper.implementationPackage().get() : + next().implementationPackage(); + } + + @Override + public Set uses() { + return toDeclaredTypes( mapper.uses().get(), next().uses() ); + } + + @Override + public Set imports() { + return toDeclaredTypes( mapper.imports().get(), next().imports() ); + } + + @Override + public ReportingPolicyGem unmappedTargetPolicy() { + return mapper.unmappedTargetPolicy().hasValue() ? + ReportingPolicyGem.valueOf( mapper.unmappedTargetPolicy().get() ) : next().unmappedTargetPolicy(); + } + + @Override + public ReportingPolicyGem unmappedSourcePolicy() { + return mapper.unmappedSourcePolicy().hasValue() ? + ReportingPolicyGem.valueOf( mapper.unmappedSourcePolicy().get() ) : next().unmappedSourcePolicy(); + } + + @Override + public ReportingPolicyGem typeConversionPolicy() { + return mapper.typeConversionPolicy().hasValue() ? + ReportingPolicyGem.valueOf( mapper.typeConversionPolicy().get() ) : next().typeConversionPolicy(); + } + + @Override + public String componentModel() { + return mapper.componentModel().hasValue() ? mapper.componentModel().get() : next().componentModel(); + } + + @Override + public boolean suppressTimestampInGenerated() { + return mapper.suppressTimestampInGenerated().hasValue() ? + mapper.suppressTimestampInGenerated().get() : + next().suppressTimestampInGenerated(); + } + + @Override + public MappingInheritanceStrategyGem getMappingInheritanceStrategy() { + return mapper.mappingInheritanceStrategy().hasValue() ? + MappingInheritanceStrategyGem.valueOf( mapper.mappingInheritanceStrategy().get() ) : + next().getMappingInheritanceStrategy(); + } + + @Override + public InjectionStrategyGem getInjectionStrategy() { + return mapper.injectionStrategy().hasValue() ? + InjectionStrategyGem.valueOf( mapper.injectionStrategy().get() ) : + next().getInjectionStrategy(); + } + + @Override + public Boolean isDisableSubMappingMethodsGeneration() { + return mapper.disableSubMappingMethodsGeneration().hasValue() ? + mapper.disableSubMappingMethodsGeneration().get() : + next().isDisableSubMappingMethodsGeneration(); + } + + // @Mapping, @BeanMapping + + @Override + public CollectionMappingStrategyGem getCollectionMappingStrategy() { + return mapper.collectionMappingStrategy().hasValue() ? + CollectionMappingStrategyGem.valueOf( mapper.collectionMappingStrategy().get() ) : + next().getCollectionMappingStrategy(); + } + + @Override + public NullValueCheckStrategyGem getNullValueCheckStrategy() { + return mapper.nullValueCheckStrategy().hasValue() ? + NullValueCheckStrategyGem.valueOf( mapper.nullValueCheckStrategy().get() ) : + next().getNullValueCheckStrategy(); + } + + @Override + public NullValuePropertyMappingStrategyGem getNullValuePropertyMappingStrategy() { + return mapper.nullValuePropertyMappingStrategy().hasValue() ? + NullValuePropertyMappingStrategyGem.valueOf( mapper.nullValuePropertyMappingStrategy().get() ) : + next().getNullValuePropertyMappingStrategy(); + } + + @Override + public NullValueMappingStrategyGem getNullValueMappingStrategy() { + return mapper.nullValueMappingStrategy().hasValue() ? + NullValueMappingStrategyGem.valueOf( mapper.nullValueMappingStrategy().get() ) : + next().getNullValueMappingStrategy(); + } + + @Override + public SubclassExhaustiveStrategyGem getSubclassExhaustiveStrategy() { + return mapper.subclassExhaustiveStrategy().hasValue() ? + SubclassExhaustiveStrategyGem.valueOf( mapper.subclassExhaustiveStrategy().get() ) : + next().getSubclassExhaustiveStrategy(); + } + + @Override + public ClassAccessibilityGem accessibility() { + return mapper.accessibility().hasValue() ? + ClassAccessibilityGem.valueOf( mapper.accessibility().get() ) : + next().accessibility(); + } + + @Override + public TypeMirror getSubclassExhaustiveException() { + return mapper.subclassExhaustiveException().hasValue() ? + mapper.subclassExhaustiveException().get() : + next().getSubclassExhaustiveException(); + } + + @Override + public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() { + if ( mapper.nullValueIterableMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapper.nullValueIterableMappingStrategy().get() ); + } + if ( mapper.nullValueMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapper.nullValueMappingStrategy().get() ); + } + return next().getNullValueIterableMappingStrategy(); + } + + @Override + public NullValueMappingStrategyGem getNullValueMapMappingStrategy() { + if ( mapper.nullValueMapMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapper.nullValueMapMappingStrategy().get() ); + } + if ( mapper.nullValueMappingStrategy().hasValue() ) { + return NullValueMappingStrategyGem.valueOf( mapper.nullValueMappingStrategy().get() ); + } + return next().getNullValueMapMappingStrategy(); + } + + @Override + public BuilderGem getBuilder() { + return mapper.builder().hasValue() ? mapper.builder().get() : next().getBuilder(); + } + + @Override + public MappingControl getMappingControl(ElementUtils elementUtils) { + return mapper.mappingControl().hasValue() ? + MappingControl.fromTypeMirror( mapper.mappingControl().getValue(), elementUtils ) : + next().getMappingControl( elementUtils ); + } + + @Override + public TypeMirror getUnexpectedValueMappingException() { + return mapper.unexpectedValueMappingException().hasValue() ? + mapper.unexpectedValueMappingException().get() : + next().getUnexpectedValueMappingException(); + } + + // @Mapper specific + + public DeclaredType mapperConfigType() { + return mapperConfigType; + } + + public boolean hasMapperConfig() { + return mapperConfigType != null; + } + + public boolean isValid() { + return mapper.isValid(); + } + + public AnnotationMirror getAnnotationMirror() { + return mapper.mirror(); + } + + @Override + public boolean hasAnnotation() { + return true; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java deleted file mode 100644 index 7f695b386c..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Mapping.java +++ /dev/null @@ -1,566 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.ElementKind; -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.model.common.FormattingParameters; -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.prism.MappingPrism; -import org.mapstruct.ap.internal.prism.MappingsPrism; -import org.mapstruct.ap.internal.util.AccessorNamingUtils; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; -import org.mapstruct.ap.internal.util.Strings; - -/** - * Represents a property mapping as configured via {@code @Mapping}. - * - * @author Gunnar Morling - */ -public class Mapping { - - private static final Pattern JAVA_EXPRESSION = Pattern.compile( "^java\\((.*)\\)$" ); - - private final String sourceName; - private final String constant; - private final String javaExpression; - private final String defaultJavaExpression; - private final String targetName; - private final String defaultValue; - private final FormattingParameters formattingParameters; - private final SelectionParameters selectionParameters; - - private final boolean isIgnored; - private final List dependsOn; - - private final AnnotationMirror mirror; - private final AnnotationValue sourceAnnotationValue; - private final AnnotationValue targetAnnotationValue; - private final AnnotationValue dependsOnAnnotationValue; - - private SourceReference sourceReference; - private TargetReference targetReference; - - public static Map> fromMappingsPrism(MappingsPrism mappingsAnnotation, - ExecutableElement method, FormattingMessager messager, Types typeUtils) { - Map> mappings = new HashMap>(); - - for ( MappingPrism mappingPrism : mappingsAnnotation.value() ) { - Mapping mapping = fromMappingPrism( mappingPrism, method, messager, typeUtils ); - if ( mapping != null ) { - List mappingsOfProperty = mappings.get( mappingPrism.target() ); - if ( mappingsOfProperty == null ) { - mappingsOfProperty = new ArrayList(); - mappings.put( mappingPrism.target(), mappingsOfProperty ); - } - - mappingsOfProperty.add( mapping ); - - if ( mappingsOfProperty.size() > 1 && !isEnumType( method.getReturnType() ) ) { - messager.printMessage( method, Message.PROPERTYMAPPING_DUPLICATE_TARGETS, mappingPrism.target() ); - } - } - } - - return mappings; - } - - public static Mapping fromMappingPrism(MappingPrism mappingPrism, ExecutableElement element, - FormattingMessager messager, Types typeUtils) { - - if ( mappingPrism.target().isEmpty() ) { - messager.printMessage( - element, - mappingPrism.mirror, - mappingPrism.values.target(), - Message.PROPERTYMAPPING_EMPTY_TARGET - ); - return null; - } - - if ( !mappingPrism.source().isEmpty() && mappingPrism.values.constant() != null ) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_SOURCE_AND_CONSTANT_BOTH_DEFINED ); - return null; - } - else if ( !mappingPrism.source().isEmpty() && mappingPrism.values.expression() != null ) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_SOURCE_AND_EXPRESSION_BOTH_DEFINED ); - return null; - } - else if ( mappingPrism.values.expression() != null && mappingPrism.values.constant() != null ) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_EXPRESSION_AND_CONSTANT_BOTH_DEFINED ); - return null; - } - else if ( mappingPrism.values.expression() != null && mappingPrism.values.defaultValue() != null ) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_VALUE_BOTH_DEFINED ); - return null; - } - else if ( mappingPrism.values.constant() != null && mappingPrism.values.defaultValue() != null ) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_CONSTANT_AND_DEFAULT_VALUE_BOTH_DEFINED ); - return null; - } - else if ( mappingPrism.values.expression() != null && mappingPrism.values.defaultExpression() != null) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_EXPRESSION_BOTH_DEFINED ); - return null; - } - else if ( mappingPrism.values.constant() != null && mappingPrism.values.defaultExpression() != null) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_CONSTANT_AND_DEFAULT_EXPRESSION_BOTH_DEFINED ); - return null; - } - else if ( mappingPrism.values.defaultValue() != null && mappingPrism.values.defaultExpression() != null) { - messager.printMessage( - element, - mappingPrism.mirror, - Message.PROPERTYMAPPING_DEFAULT_VALUE_AND_DEFAULT_EXPRESSION_BOTH_DEFINED ); - return null; - } - - String source = mappingPrism.source().isEmpty() ? null : mappingPrism.source(); - String constant = mappingPrism.values.constant() == null ? null : mappingPrism.constant(); - String expression = getExpression( mappingPrism, element, messager ); - String defaultExpression = getDefaultExpression( mappingPrism, element, messager ); - String dateFormat = mappingPrism.values.dateFormat() == null ? null : mappingPrism.dateFormat(); - String numberFormat = mappingPrism.values.numberFormat() == null ? null : mappingPrism.numberFormat(); - String defaultValue = mappingPrism.values.defaultValue() == null ? null : mappingPrism.defaultValue(); - - boolean resultTypeIsDefined = mappingPrism.values.resultType() != null; - List dependsOn = - mappingPrism.dependsOn() != null ? mappingPrism.dependsOn() : Collections.emptyList(); - - - FormattingParameters formattingParam = new FormattingParameters( - dateFormat, - numberFormat, - mappingPrism.mirror, - mappingPrism.values.dateFormat(), - element - ); - SelectionParameters selectionParams = new SelectionParameters( - mappingPrism.qualifiedBy(), - mappingPrism.qualifiedByName(), - resultTypeIsDefined ? mappingPrism.resultType() : null, - typeUtils - ); - - return new Mapping( - source, - constant, - expression, - defaultExpression, - mappingPrism.target(), - defaultValue, - mappingPrism.ignore(), - mappingPrism.mirror, - mappingPrism.values.source(), - mappingPrism.values.target(), - formattingParam, - selectionParams, - mappingPrism.values.dependsOn(), - dependsOn - ); - } - - public static Mapping forIgnore( String targetName) { - return new Mapping( - null, - null, - null, - null, - targetName, - null, - true, - null, - null, - null, - null, - null, - null, - new ArrayList() - ); - } - - @SuppressWarnings("checkstyle:parameternumber") - private Mapping( String sourceName, String constant, String javaExpression, String defaultJavaExpression, - String targetName, String defaultValue, boolean isIgnored, AnnotationMirror mirror, - AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue, - FormattingParameters formattingParameters, SelectionParameters selectionParameters, - AnnotationValue dependsOnAnnotationValue, List dependsOn ) { - this.sourceName = sourceName; - this.constant = constant; - this.javaExpression = javaExpression; - this.defaultJavaExpression = defaultJavaExpression; - this.targetName = targetName; - this.defaultValue = defaultValue; - this.isIgnored = isIgnored; - this.mirror = mirror; - this.sourceAnnotationValue = sourceAnnotationValue; - this.targetAnnotationValue = targetAnnotationValue; - this.formattingParameters = formattingParameters; - this.selectionParameters = selectionParameters; - this.dependsOnAnnotationValue = dependsOnAnnotationValue; - this.dependsOn = dependsOn; - } - - private Mapping( Mapping mapping, TargetReference targetReference ) { - this.sourceName = mapping.sourceName; - this.constant = mapping.constant; - this.javaExpression = mapping.javaExpression; - this.defaultJavaExpression = mapping.defaultJavaExpression; - this.targetName = Strings.join( targetReference.getElementNames(), "." ); - this.defaultValue = mapping.defaultValue; - this.isIgnored = mapping.isIgnored; - this.mirror = mapping.mirror; - this.sourceAnnotationValue = mapping.sourceAnnotationValue; - this.targetAnnotationValue = mapping.targetAnnotationValue; - this.formattingParameters = mapping.formattingParameters; - this.selectionParameters = mapping.selectionParameters; - this.dependsOnAnnotationValue = mapping.dependsOnAnnotationValue; - this.dependsOn = mapping.dependsOn; - this.sourceReference = mapping.sourceReference; - this.targetReference = targetReference; - } - - private Mapping( Mapping mapping, SourceReference sourceReference ) { - this.sourceName = Strings.join( sourceReference.getElementNames(), "." ); - this.constant = mapping.constant; - this.javaExpression = mapping.javaExpression; - this.defaultJavaExpression = mapping.defaultJavaExpression; - this.targetName = mapping.targetName; - this.defaultValue = mapping.defaultValue; - this.isIgnored = mapping.isIgnored; - this.mirror = mapping.mirror; - this.sourceAnnotationValue = mapping.sourceAnnotationValue; - this.targetAnnotationValue = mapping.targetAnnotationValue; - this.formattingParameters = mapping.formattingParameters; - this.selectionParameters = mapping.selectionParameters; - this.dependsOnAnnotationValue = mapping.dependsOnAnnotationValue; - this.dependsOn = mapping.dependsOn; - this.sourceReference = sourceReference; - this.targetReference = mapping.targetReference; - } - - private static String getExpression(MappingPrism mappingPrism, ExecutableElement element, - FormattingMessager messager) { - if ( mappingPrism.expression().isEmpty() ) { - return null; - } - - Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mappingPrism.expression() ); - - if ( !javaExpressionMatcher.matches() ) { - messager.printMessage( - element, mappingPrism.mirror, mappingPrism.values.expression(), - Message.PROPERTYMAPPING_INVALID_EXPRESSION - ); - return null; - } - - return javaExpressionMatcher.group( 1 ).trim(); - } - - private static String getDefaultExpression(MappingPrism mappingPrism, ExecutableElement element, - FormattingMessager messager) { - if ( mappingPrism.defaultExpression().isEmpty() ) { - return null; - } - - Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mappingPrism.defaultExpression() ); - - if ( !javaExpressionMatcher.matches() ) { - messager.printMessage( - element, mappingPrism.mirror, mappingPrism.values.defaultExpression(), - Message.PROPERTYMAPPING_INVALID_DEFAULT_EXPRESSION - ); - return null; - } - - return javaExpressionMatcher.group( 1 ).trim(); - } - - private static boolean isEnumType(TypeMirror mirror) { - return mirror.getKind() == TypeKind.DECLARED && - ( (DeclaredType) mirror ).asElement().getKind() == ElementKind.ENUM; - } - - public void init(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory, - AccessorNamingUtils accessorNaming) { - init( method, messager, typeFactory, accessorNaming, false, null ); - } - - /** - * Initialize the Mapping. - * - * @param method the source method that the mapping belongs to - * @param messager the messager that can be used for outputting messages - * @param typeFactory the type factory - * @param accessorNaming the accessor naming utils - * @param isReverse whether the init is for a reverse mapping - * @param reverseSourceParameter the source parameter from the revers mapping - */ - private void init(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory, - AccessorNamingUtils accessorNaming, boolean isReverse, - Parameter reverseSourceParameter) { - - if ( !method.isEnumMapping() ) { - sourceReference = new SourceReference.BuilderFromMapping() - .mapping( this ) - .method( method ) - .messager( messager ) - .typeFactory( typeFactory ) - .build(); - - targetReference = new TargetReference.BuilderFromTargetMapping() - .mapping( this ) - .isReverse( isReverse ) - .method( method ) - .messager( messager ) - .typeFactory( typeFactory ) - .accessorNaming( accessorNaming ) - .reverseSourceParameter( reverseSourceParameter ) - .build(); - } - } - - /** - * Initializes the mapping with a new source parameter. - * - * @param sourceParameter sets the source parameter that acts as a basis for this mapping - */ - public void init( Parameter sourceParameter ) { - if ( sourceReference != null ) { - SourceReference oldSourceReference = sourceReference; - sourceReference = new SourceReference.BuilderFromSourceReference() - .sourceParameter( sourceParameter ) - .sourceReference( oldSourceReference ) - .build(); - } - } - - /** - * Returns the complete source name of this mapping, either a qualified (e.g. {@code parameter1.foo}) or - * unqualified (e.g. {@code foo}) property reference. - * - * @return The complete source name of this mapping. - */ - public String getSourceName() { - return sourceName; - } - - public String getConstant() { - return constant; - } - - public String getJavaExpression() { - return javaExpression; - } - - public String getDefaultJavaExpression() { - return defaultJavaExpression; - } - - public String getTargetName() { - return targetName; - } - - public String getDefaultValue() { - return defaultValue; - } - - public FormattingParameters getFormattingParameters() { - return formattingParameters; - } - - public SelectionParameters getSelectionParameters() { - return selectionParameters; - } - - public boolean isIgnored() { - return isIgnored; - } - - public AnnotationMirror getMirror() { - return mirror; - } - - public AnnotationValue getSourceAnnotationValue() { - return sourceAnnotationValue; - } - - public AnnotationValue getTargetAnnotationValue() { - return targetAnnotationValue; - } - - public AnnotationValue getDependsOnAnnotationValue() { - return dependsOnAnnotationValue; - } - - public SourceReference getSourceReference() { - return sourceReference; - } - - public TargetReference getTargetReference() { - return targetReference; - } - - public Mapping popTargetReference() { - if ( targetReference != null ) { - TargetReference newTargetReference = targetReference.pop(); - if (newTargetReference != null ) { - return new Mapping(this, newTargetReference ); - } - } - return null; - } - - public Mapping popSourceReference() { - if ( sourceReference != null ) { - SourceReference newSourceReference = sourceReference.pop(); - if (newSourceReference != null ) { - return new Mapping(this, newSourceReference ); - } - } - return null; - } - - public List getDependsOn() { - return dependsOn; - } - - public Mapping reverse(SourceMethod method, FormattingMessager messager, TypeFactory typeFactory, - AccessorNamingUtils accessorNaming) { - - // mapping can only be reversed if the source was not a constant nor an expression nor a nested property - // and the mapping is not a 'target-source-ignore' mapping - if ( constant != null || javaExpression != null || ( isIgnored && sourceName == null ) ) { - return null; - } - - Mapping reverse = new Mapping( - sourceName != null ? targetName : null, - null, // constant - null, // expression - null, // defaultExpression - sourceName != null ? sourceName : targetName, - null, - isIgnored, - mirror, - sourceAnnotationValue, - targetAnnotationValue, - formattingParameters, - selectionParameters, - dependsOnAnnotationValue, - Collections.emptyList() - ); - - reverse.init( - method, - messager, - typeFactory, - accessorNaming, - true, - sourceReference != null ? sourceReference.getParameter() : null - ); - - // check if the reverse mapping has indeed a write accessor, otherwise the mapping cannot be reversed - if ( !reverse.targetReference.isValid() ) { - return null; - } - - return reverse; - } - - /** - * Creates a copy of this mapping, which is adapted to the given method - * - * @param method the method to create the copy for - * @return the copy - */ - public Mapping copyForInheritanceTo(SourceMethod method) { - Mapping mapping = new Mapping( - sourceName, - constant, - javaExpression, - defaultJavaExpression, - targetName, - defaultValue, - isIgnored, - mirror, - sourceAnnotationValue, - targetAnnotationValue, - formattingParameters, - selectionParameters, - dependsOnAnnotationValue, - dependsOn - ); - - if ( sourceReference != null ) { - mapping.sourceReference = sourceReference.copyForInheritanceTo( method ); - } - - // TODO... must something be done here? Andreas? - mapping.targetReference = targetReference; - - return mapping; - } - - @Override - public String toString() { - return "Mapping {" + - "\n sourceName='" + sourceName + "\'," + - "\n targetName='" + targetName + "\'," + - "\n}"; - } -} - diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingControl.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingControl.java new file mode 100644 index 0000000000..87448bfb65 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingControl.java @@ -0,0 +1,119 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.HashSet; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.MappingControlGem; +import org.mapstruct.ap.internal.gem.MappingControlUseGem; +import org.mapstruct.ap.internal.gem.MappingControlsGem; +import org.mapstruct.ap.internal.util.ElementUtils; + +public class MappingControl { + + private static final String JAVA_LANG_ANNOTATION_PGK = "java.lang.annotation"; + private static final String ORG_MAPSTRUCT_PKG = "org.mapstruct"; + private static final String MAPPING_CONTROL_FQN = "org.mapstruct.control.MappingControl"; + private static final String MAPPING_CONTROLS_FQN = "org.mapstruct.control.MappingControls"; + + private boolean allowDirect = false; + private boolean allowTypeConversion = false; + private boolean allowMappingMethod = false; + private boolean allow2Steps = false; + + public static MappingControl fromTypeMirror(TypeMirror mirror, ElementUtils elementUtils) { + MappingControl mappingControl = new MappingControl(); + if ( TypeKind.DECLARED == mirror.getKind() ) { + resolveControls( mappingControl, ( (DeclaredType) mirror ).asElement(), new HashSet<>(), elementUtils ); + } + return mappingControl; + } + + private MappingControl() { + } + + public boolean allowDirect() { + return allowDirect; + } + + public boolean allowTypeConversion() { + return allowTypeConversion; + } + + public boolean allowMappingMethod() { + return allowMappingMethod; + } + + public boolean allowBy2Steps() { + return allow2Steps; + } + + private static void resolveControls(MappingControl control, Element element, Set handledElements, + ElementUtils elementUtils) { + for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { + Element lElement = annotationMirror.getAnnotationType().asElement(); + if ( isAnnotation( lElement, MAPPING_CONTROL_FQN ) ) { + determineMappingControl( control, MappingControlGem.instanceOn( element ) ); + } + else if ( isAnnotation( lElement, MAPPING_CONTROLS_FQN ) ) { + MappingControlsGem.instanceOn( element ) + .value() + .get() + .forEach( m -> determineMappingControl( control, m ) ); + } + else if ( !isAnnotationInPackage( lElement, JAVA_LANG_ANNOTATION_PGK, elementUtils ) + && !isAnnotationInPackage( lElement, ORG_MAPSTRUCT_PKG, elementUtils ) + && !handledElements.contains( lElement ) + ) { + // recur over annotation mirrors + handledElements.add( lElement ); + resolveControls( control, lElement, handledElements, elementUtils ); + } + } + } + + private static void determineMappingControl(MappingControl in, MappingControlGem gem) { + MappingControlUseGem use = MappingControlUseGem.valueOf( gem.value().get() ); + switch ( use ) { + case DIRECT: + in.allowDirect = true; + break; + case MAPPING_METHOD: + in.allowMappingMethod = true; + break; + case BUILT_IN_CONVERSION: + in.allowTypeConversion = true; + break; + case COMPLEX_MAPPING: + in.allow2Steps = true; + break; + default: + } + } + + private static boolean isAnnotationInPackage(Element element, String packageFQN, ElementUtils elementUtils) { + if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) { + return packageFQN.equals( elementUtils.getPackageOf( element ).getQualifiedName().toString() ); + } + return false; + } + + private static boolean isAnnotation(Element element, String annotationFQN) { + if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) { + return annotationFQN.equals( ( (TypeElement) element ).getQualifiedName().toString() ); + } + return false; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodOptions.java new file mode 100644 index 0000000000..caf7639977 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodOptions.java @@ -0,0 +1,413 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; + +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.accessor.Accessor; + +import static org.mapstruct.ap.internal.model.source.MappingOptions.getMappingTargetNamesBy; + +/** + * Encapsulates all options specifiable on a mapping method + * + * @author Andreas Gudian + */ +public class MappingMethodOptions { + private static final MappingMethodOptions EMPTY = new MappingMethodOptions( + null, + Collections.emptySet(), + null, + null, + null, + null, + Collections.emptyList(), + Collections.emptySet(), + null + ); + + private MapperOptions mapper; + private Set mappings; + private IterableMappingOptions iterableMapping; + private MapMappingOptions mapMapping; + private BeanMappingOptions beanMapping; + private EnumMappingOptions enumMappingOptions; + private List valueMappings; + private boolean fullyInitialized; + private Set subclassMappings; + + private SubclassValidator subclassValidator; + + public MappingMethodOptions(MapperOptions mapper, Set mappings, + IterableMappingOptions iterableMapping, + MapMappingOptions mapMapping, BeanMappingOptions beanMapping, + EnumMappingOptions enumMappingOptions, + List valueMappings, + Set subclassMappings, SubclassValidator subclassValidator) { + this.mapper = mapper; + this.mappings = mappings; + this.iterableMapping = iterableMapping; + this.mapMapping = mapMapping; + this.beanMapping = beanMapping; + this.enumMappingOptions = enumMappingOptions; + this.valueMappings = valueMappings; + this.subclassMappings = subclassMappings; + this.subclassValidator = subclassValidator; + } + + /** + * creates empty mapping options + * + * @return empty mapping options + */ + public static MappingMethodOptions empty() { + return EMPTY; + } + + /** + * @return the {@link MappingOptions}s configured for this method, keyed by target property name. Only for enum + * mapping methods a target will be mapped by several sources. + */ + public Set getMappings() { + return mappings; + } + + public IterableMappingOptions getIterableMapping() { + return iterableMapping; + } + + public MapMappingOptions getMapMapping() { + return mapMapping; + } + + public BeanMappingOptions getBeanMapping() { + return beanMapping; + } + + public EnumMappingOptions getEnumMappingOptions() { + return enumMappingOptions; + } + + public List getValueMappings() { + return valueMappings; + } + + public Set getSubclassMappings() { + return subclassMappings; + } + + public void setIterableMapping(IterableMappingOptions iterableMapping) { + this.iterableMapping = iterableMapping; + } + + public void setMapMapping(MapMappingOptions mapMapping) { + this.mapMapping = mapMapping; + } + + public void setBeanMapping(BeanMappingOptions beanMapping) { + this.beanMapping = beanMapping; + } + + public void setEnumMappingOptions(EnumMappingOptions enumMappingOptions) { + this.enumMappingOptions = enumMappingOptions; + } + + public void setValueMappings(List valueMappings) { + this.valueMappings = valueMappings; + } + + public MapperOptions getMapper() { + return mapper; + } + + /** + * @return the {@code true}, iff the options have been fully initialized by applying all available inheritance + * options + */ + public boolean isFullyInitialized() { + return fullyInitialized; + } + + public void markAsFullyInitialized() { + this.fullyInitialized = true; + } + + /** + * Merges in all the mapping options configured, giving the already defined options precedence. + * + * @param sourceMethod the method which inherits the options. + * @param templateMethod the template method with the options to inherit, may be {@code null} + * @param isInverse if {@code true}, the specified options are from an inverse method + * @param annotationMirror the annotation on which the compile errors will be shown. + */ + public void applyInheritedOptions(SourceMethod sourceMethod, SourceMethod templateMethod, boolean isInverse, + AnnotationMirror annotationMirror) { + MappingMethodOptions templateOptions = templateMethod.getOptions(); + if ( null != templateOptions ) { + if ( !getIterableMapping().hasAnnotation() && templateOptions.getIterableMapping().hasAnnotation() ) { + setIterableMapping( templateOptions.getIterableMapping() ); + } + + if ( !getMapMapping().hasAnnotation() && templateOptions.getMapMapping().hasAnnotation() ) { + setMapMapping( templateOptions.getMapMapping() ); + } + + if ( !getBeanMapping().hasAnnotation() && templateOptions.getBeanMapping().hasAnnotation() ) { + setBeanMapping( BeanMappingOptions.forInheritance( templateOptions.getBeanMapping( ), isInverse ) ); + } + + if ( !getEnumMappingOptions().hasAnnotation() && templateOptions.getEnumMappingOptions().hasAnnotation() ) { + EnumMappingOptions newEnumMappingOptions; + if ( isInverse ) { + newEnumMappingOptions = templateOptions.getEnumMappingOptions().inverse(); + } + else { + newEnumMappingOptions = templateOptions.getEnumMappingOptions(); + } + setEnumMappingOptions( newEnumMappingOptions ); + } + + if ( getValueMappings() == null ) { + if ( templateOptions.getValueMappings() != null ) { + // there were no mappings, so the inherited mappings are the new ones + setValueMappings( templateOptions.getValueMappings() ); + } + else { + setValueMappings( Collections.emptyList() ); + } + } + else { + if ( templateOptions.getValueMappings() != null ) { + // if there are also inherited mappings, we inverse and add them. + for ( ValueMappingOptions inheritedValueMapping : templateOptions.getValueMappings() ) { + ValueMappingOptions valueMapping = + isInverse ? inheritedValueMapping.inverse() : inheritedValueMapping; + if ( valueMapping != null + && !getValueMappings().contains( valueMapping ) ) { + getValueMappings().add( valueMapping ); + } + } + } + } + + if ( isInverse ) { + List inheritedMappings = SubclassMappingOptions.copyForInverseInheritance( + templateOptions.getSubclassMappings(), + getBeanMapping() ); + addAllNonRedefined( sourceMethod, annotationMirror, inheritedMappings ); + } + else if ( methodsHaveIdenticalSignature( templateMethod, sourceMethod ) ) { + List inheritedMappings = + SubclassMappingOptions + .copyForInheritance( + templateOptions.getSubclassMappings(), + getBeanMapping() ); + addAllNonRedefined( sourceMethod, annotationMirror, inheritedMappings ); + } + + Set newMappings = new LinkedHashSet<>(); + for ( MappingOptions mapping : templateOptions.getMappings() ) { + if ( isInverse ) { + if ( mapping.canInverse() ) { + newMappings.add( mapping.copyForInverseInheritance( templateMethod, getBeanMapping() ) ); + } + } + else { + newMappings.add( mapping.copyForForwardInheritance( templateMethod, getBeanMapping() ) ); + } + } + + // now add all (does not override duplicates and leaves original mappings) + addAllNonRedefined( newMappings ); + + // filter new mappings + filterNestedTargetIgnores( mappings ); + } + } + + private boolean methodsHaveIdenticalSignature(SourceMethod templateMethod, SourceMethod sourceMethod) { + return parametersAreOfIdenticalTypeAndOrder( templateMethod, sourceMethod ) + && resultTypeIsTheSame( templateMethod, sourceMethod ); + } + + private boolean parametersAreOfIdenticalTypeAndOrder(SourceMethod templateMethod, SourceMethod sourceMethod) { + if ( templateMethod.getParameters().size() != sourceMethod.getParameters().size() ) { + return false; + } + for ( int i = 0; i < templateMethod.getParameters().size(); i++ ) { + if ( !templateMethod.getParameters().get( i ).getType().equals( + sourceMethod.getParameters().get( i ).getType() ) ) { + return false; + } + } + return true; + } + + private boolean resultTypeIsTheSame(SourceMethod templateMethod, SourceMethod sourceMethod) { + return templateMethod.getResultType().equals( sourceMethod.getResultType() ); + } + + private void addAllNonRedefined(SourceMethod sourceMethod, AnnotationMirror annotationMirror, + List inheritedMappings) { + Set redefinedSubclassMappings = new HashSet<>( subclassMappings ); + for ( SubclassMappingOptions subclassMappingOption : inheritedMappings ) { + if ( !redefinedSubclassMappings.contains( subclassMappingOption ) ) { + if ( subclassValidator.isValidUsage( + sourceMethod.getExecutable(), + annotationMirror, + subclassMappingOption.getSource() ) ) { + subclassMappings.add( subclassMappingOption ); + } + } + } + } + + private void addAllNonRedefined(Set inheritedMappings) { + // We are only adding the targets here since this mappings have already been reversed + Set redefinedTargets = new HashSet<>(); + for ( MappingOptions redefinedMappings : mappings ) { + if ( redefinedMappings.getTargetName() != null ) { + redefinedTargets.add( redefinedMappings.getTargetName() ); + } + } + for ( MappingOptions inheritedMapping : inheritedMappings ) { + if ( inheritedMapping.isIgnored() + || !isRedefined( redefinedTargets, inheritedMapping.getTargetName() ) + ) { + mappings.add( inheritedMapping ); + } + } + } + + private boolean isRedefined(Set redefinedNames, String inheritedName ) { + if ( inheritedName != null ) { + for ( String redefinedName : redefinedNames ) { + if ( elementsAreContainedIn( inheritedName, redefinedName ) ) { + return true; + } + } + } + return false; + } + + private boolean elementsAreContainedIn( String redefinedName, String inheritedName ) { + if ( inheritedName != null && redefinedName.startsWith( inheritedName ) ) { + // it is possible to redefine an exact matching source name, because the same source can be mapped to + // multiple targets. It is not possible for target, but caught by the Set and equals method in + // MappingOptions. SourceName == null also could hint at redefinition + if ( redefinedName.length() > inheritedName.length() ) { + // redefined.lenght() > inherited.length(), first following character should be separator + return '.' == redefinedName.charAt( inheritedName.length() ); + } + } + return false; + } + + public void applyIgnoreAll(SourceMethod method, TypeFactory typeFactory, + FormattingMessager messager) { + CollectionMappingStrategyGem cms = method.getOptions().getMapper().getCollectionMappingStrategy(); + Type writeType = method.getResultType(); + if ( !method.isUpdateMethod() ) { + writeType = typeFactory.effectiveResultTypeFor( + writeType, + method.getOptions().getBeanMapping().getBuilder() + ); + } + Map writeAccessors = writeType.getPropertyWriteAccessors( cms ); + + + for ( MappingOptions mapping : mappings ) { + String mappedTargetProperty = getFirstTargetPropertyName( mapping ); + if ( !".".equals( mappedTargetProperty ) ) { + // Remove the mapped target property from the write accessors + writeAccessors.remove( mappedTargetProperty ); + } + else { + messager.printMessage( + method.getExecutable(), + getBeanMapping().getMirror(), + Message.BEANMAPPING_IGNORE_BY_DEFAULT_WITH_MAPPING_TARGET_THIS + ); + // Nothing more to do if this is reached + return; + } + } + + // The writeAccessors now contains only the accessors that should be ignored + for ( String targetPropertyName : writeAccessors.keySet() ) { + MappingOptions mapping = MappingOptions.forIgnore( targetPropertyName ); + mappings.add( mapping ); + } + } + + private void filterNestedTargetIgnores( Set mappings) { + + // collect all properties to ignore, and safe their target name ( == same name as first ref target property) + Set ignored = getMappingTargetNamesBy( MappingOptions::isIgnored, mappings ); + mappings.removeIf( m -> isToBeIgnored( ignored, m ) ); + } + + private boolean isToBeIgnored(Set ignored, MappingOptions mapping) { + String[] propertyEntries = getPropertyEntries( mapping ); + return propertyEntries.length > 1 && ignored.contains( propertyEntries[ 0 ] ); + } + + private String[] getPropertyEntries( MappingOptions mapping ) { + return mapping.getTargetName().split( "\\." ); + } + + private String getFirstTargetPropertyName(MappingOptions mapping) { + String targetName = mapping.getTargetName(); + if ( ".".equals( targetName ) ) { + return targetName; + } + + return getPropertyEntries( mapping )[0]; + } + + /** + * SubclassMappingOptions are not inherited to forged methods. They would result in an infinite loop if they were. + * + * @return a MappingMethodOptions without SubclassMappingOptions or SubclassValidator. + */ + public static MappingMethodOptions getForgedMethodInheritedOptions(MappingMethodOptions options) { + return new MappingMethodOptions( + options.mapper, + options.mappings, + options.iterableMapping, + options.mapMapping, + BeanMappingOptions.forForgedMethods( options.beanMapping ), + options.enumMappingOptions, + options.valueMappings, + Collections.emptySet(), + null ); + } + + public static MappingMethodOptions getSubclassForgedMethodInheritedOptions(MappingMethodOptions options) { + return new MappingMethodOptions( + options.mapper, + options.mappings, + options.iterableMapping, + options.mapMapping, + BeanMappingOptions.forSubclassForgedMethods( options.beanMapping ), + options.enumMappingOptions, + options.valueMappings, + Collections.emptySet(), + null ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java index d38451785a..7d0ab3a7ec 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingMethodUtils.java @@ -1,26 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; +import org.mapstruct.ap.internal.model.common.Type; + import static org.mapstruct.ap.internal.util.Collections.first; /** + * Utility class for mapping methods. + * * @author Filip Hrisafov */ public final class MappingMethodUtils { @@ -31,18 +22,34 @@ public final class MappingMethodUtils { private MappingMethodUtils() { } - /** * Checks if the provided {@code method} is for enum mapping. A Method is an Enum Mapping method when the - * source parameter and result type are enum types. + *

      + *
    1. source parameter type and result type are enum types
    2. + *
    3. source parameter type is a String and result type is an enum type
    4. + *
    5. source parameter type is a enum type and result type is a String
    6. + *
    * * @param method to check * * @return {@code true} if the method is for enum mapping, {@code false} otherwise */ public static boolean isEnumMapping(Method method) { - return method.getSourceParameters().size() == 1 - && first( method.getSourceParameters() ).getType().isEnumType() - && method.getResultType().isEnumType(); + if ( method.getSourceParameters().size() != 1 ) { + return false; + } + + Type source = first( method.getSourceParameters() ).getType(); + Type result = method.getResultType(); + if ( source.isEnumType() && result.isEnumType() ) { + return true; + } + if ( source.isString() && result.isEnumType() ) { + return true; + } + if ( source.isEnumType() && result.isString() ) { + return true; + } + return false; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java index 62cb0dd3df..746aca5a32 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MappingOptions.java @@ -1,355 +1,586 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; -import static org.mapstruct.ap.internal.util.Collections.first; - -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; +import java.util.LinkedHashSet; +import java.util.Objects; +import java.util.Optional; import java.util.Set; - -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; -import org.mapstruct.ap.internal.util.AccessorNamingUtils; +import java.util.function.Predicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; + +import org.mapstruct.ap.internal.gem.MappingGem; +import org.mapstruct.ap.internal.gem.MappingsGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValuePropertyMappingStrategyGem; +import org.mapstruct.ap.internal.model.common.FormattingParameters; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.accessor.Accessor; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.tools.gem.GemValue; /** - * Encapsulates all options specifiable on a mapping method + * Represents a property mapping as configured via {@code @Mapping} (no intermediate state). * - * @author Andreas Gudian + * @author Gunnar Morling */ -public class MappingOptions { - private static final MappingOptions EMPTY = new MappingOptions( Collections.>emptyMap(), - null, - null, - null, - Collections.emptyList(), - false - ); - private Map> mappings; - private IterableMapping iterableMapping; - private MapMapping mapMapping; - private BeanMapping beanMapping; - private List valueMappings; - private boolean fullyInitialized; - private final boolean restrictToDefinedMappings; - - public MappingOptions(Map> mappings, IterableMapping iterableMapping, MapMapping mapMapping, - BeanMapping beanMapping, List valueMappings, boolean restrictToDefinedMappings ) { - this.mappings = mappings; - this.iterableMapping = iterableMapping; - this.mapMapping = mapMapping; - this.beanMapping = beanMapping; - this.valueMappings = valueMappings; - this.restrictToDefinedMappings = restrictToDefinedMappings; +public class MappingOptions extends DelegatingOptions { + + private static final Pattern JAVA_EXPRESSION = Pattern.compile( "^\\s*java\\((.*)\\)\\s*$", Pattern.DOTALL ); + + private final String sourceName; + private final String constant; + private final String javaExpression; + private final String defaultJavaExpression; + private final String conditionJavaExpression; + private final String targetName; + private final String defaultValue; + private final FormattingParameters formattingParameters; + private final SelectionParameters selectionParameters; + + private final boolean isIgnored; + private final Set dependsOn; + + private final Element element; + private final AnnotationValue sourceAnnotationValue; + private final AnnotationValue targetAnnotationValue; + private final MappingGem mapping; + + private final InheritContext inheritContext; + + public static class InheritContext { + + private final boolean isReversed; + private final boolean isForwarded; + private final Method templateMethod; + + public InheritContext(boolean isReversed, boolean isForwarded, Method templateMethod) { + this.isReversed = isReversed; + this.isForwarded = isForwarded; + this.templateMethod = templateMethod; + } + + public boolean isReversed() { + return isReversed; + } + + public boolean isForwarded() { + return isForwarded; + } + + public Method getTemplateMethod() { + return templateMethod; + } } - /** - * creates empty mapping options - * - * @return empty mapping options - */ - public static MappingOptions empty() { - return EMPTY; + public static Set getMappingTargetNamesBy(Predicate predicate, + Set mappings) { + return mappings.stream() + .filter( predicate ) + .map( MappingOptions::getTargetName ) + .collect( Collectors.toCollection( LinkedHashSet::new ) ); } - /** - * creates mapping options with only regular mappings - * - * @param mappings regular mappings to add - * @param restrictToDefinedMappings whether to restrict the mappings only to the defined mappings - * @return MappingOptions with only regular mappings - */ - public static MappingOptions forMappingsOnly(Map> mappings, - boolean restrictToDefinedMappings) { - return forMappingsOnly( mappings, restrictToDefinedMappings, restrictToDefinedMappings ); + public static void addInstances(MappingsGem gem, ExecutableElement method, + BeanMappingOptions beanMappingOptions, + FormattingMessager messager, TypeUtils typeUtils, + Set mappings) { + for ( MappingGem mapping : gem.value().getValue() ) { + addInstance( mapping, method, beanMappingOptions, messager, typeUtils, mappings ); + } } - /** - * creates mapping options with only regular mappings - * - * @param mappings regular mappings to add - * @param restrictToDefinedMappings whether to restrict the mappings only to the defined mappings - * @param forForgedMethods whether the mappings are for forged methods - * @return MappingOptions with only regular mappings - */ - public static MappingOptions forMappingsOnly(Map> mappings, - boolean restrictToDefinedMappings, boolean forForgedMethods) { + public static void addInstance(MappingGem mapping, ExecutableElement method, + BeanMappingOptions beanMappingOptions, FormattingMessager messager, + TypeUtils typeUtils, + Set mappings) { + + if ( !isConsistent( mapping, method, messager ) ) { + return; + } + + String source = mapping.source().getValue(); + String constant = mapping.constant().getValue(); + String expression = getExpression( mapping, method, messager ); + String defaultExpression = getDefaultExpression( mapping, method, messager ); + String conditionExpression = getConditionExpression( mapping, method, messager ); + String dateFormat = mapping.dateFormat().getValue(); + String numberFormat = mapping.numberFormat().getValue(); + String locale = mapping.locale().getValue(); + + String defaultValue = mapping.defaultValue().getValue(); + + Set dependsOn = mapping.dependsOn().hasValue() ? + new LinkedHashSet<>( mapping.dependsOn().getValue() ) : + Collections.emptySet(); + + FormattingParameters formattingParam = new FormattingParameters( + dateFormat, + numberFormat, + mapping.mirror(), + mapping.dateFormat().getAnnotationValue(), + method, + locale + ); + SelectionParameters selectionParams = new SelectionParameters( + mapping.qualifiedBy().get(), + mapping.qualifiedByName().get(), + mapping.conditionQualifiedBy().get(), + mapping.conditionQualifiedByName().get(), + mapping.resultType().getValue(), + typeUtils + ); + + MappingOptions options = new MappingOptions( + mapping.target().getValue(), + method, + mapping.target().getAnnotationValue(), + source, + mapping.source().getAnnotationValue(), + constant, + expression, + defaultExpression, + conditionExpression, + defaultValue, + mapping.ignore().get(), + formattingParam, + selectionParams, + dependsOn, + mapping, + null, + beanMappingOptions + ); + + if ( mappings.contains( options ) ) { + messager.printMessage( method, Message.PROPERTYMAPPING_DUPLICATE_TARGETS, mapping.target().get() ); + } + else { + mappings.add( options ); + } + } + + public static MappingOptions forIgnore(String targetName) { return new MappingOptions( - mappings, + targetName, + null, + null, + null, + null, + null, + null, + null, + null, null, + true, null, - forForgedMethods ? BeanMapping.forForgedMethods() : null, - Collections.emptyList(), - restrictToDefinedMappings + SelectionParameters.empty(), + Collections.emptySet(), + null, + null, + null ); + } + + private static boolean isConsistent(MappingGem gem, ExecutableElement method, + FormattingMessager messager) { + + if ( !gem.target().hasValue() ) { + messager.printMessage( + method, + gem.mirror(), + gem.target().getAnnotationValue(), + Message.PROPERTYMAPPING_EMPTY_TARGET + ); + return false; + } + + Message message = null; + if ( gem.source().hasValue() && gem.constant().hasValue() ) { + message = Message.PROPERTYMAPPING_SOURCE_AND_CONSTANT_BOTH_DEFINED; + } + else if ( gem.expression().hasValue() && gem.conditionQualifiedByName().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_CONDITION_QUALIFIED_BY_NAME_BOTH_DEFINED; + } + else if ( gem.source().hasValue() && gem.expression().hasValue() ) { + message = Message.PROPERTYMAPPING_SOURCE_AND_EXPRESSION_BOTH_DEFINED; + } + else if ( gem.expression().hasValue() && gem.constant().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_CONSTANT_BOTH_DEFINED; + } + else if ( gem.expression().hasValue() && gem.defaultValue().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_VALUE_BOTH_DEFINED; + } + else if ( gem.constant().hasValue() && gem.defaultValue().hasValue() ) { + message = Message.PROPERTYMAPPING_CONSTANT_AND_DEFAULT_VALUE_BOTH_DEFINED; + } + else if ( gem.expression().hasValue() && gem.defaultExpression().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_EXPRESSION_BOTH_DEFINED; + } + else if ( gem.expression().hasValue() && gem.conditionExpression().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_CONDITION_EXPRESSION_BOTH_DEFINED; + } + else if ( gem.constant().hasValue() && gem.defaultExpression().hasValue() ) { + message = Message.PROPERTYMAPPING_CONSTANT_AND_DEFAULT_EXPRESSION_BOTH_DEFINED; + } + else if ( gem.constant().hasValue() && gem.conditionExpression().hasValue() ) { + message = Message.PROPERTYMAPPING_CONSTANT_AND_CONDITION_EXPRESSION_BOTH_DEFINED; + } + else if ( gem.defaultValue().hasValue() && gem.defaultExpression().hasValue() ) { + message = Message.PROPERTYMAPPING_DEFAULT_VALUE_AND_DEFAULT_EXPRESSION_BOTH_DEFINED; + } + else if ( gem.expression().hasValue() + && ( gem.qualifiedByName().hasValue() || gem.qualifiedBy().hasValue() ) ) { + message = Message.PROPERTYMAPPING_EXPRESSION_AND_QUALIFIER_BOTH_DEFINED; + } + else if ( gem.nullValuePropertyMappingStrategy().hasValue() && gem.defaultValue().hasValue() ) { + message = Message.PROPERTYMAPPING_DEFAULT_VALUE_AND_NVPMS; + } + else if ( gem.nullValuePropertyMappingStrategy().hasValue() && gem.constant().hasValue() ) { + message = Message.PROPERTYMAPPING_CONSTANT_VALUE_AND_NVPMS; + } + else if ( gem.nullValuePropertyMappingStrategy().hasValue() && gem.expression().hasValue() ) { + message = Message.PROPERTYMAPPING_EXPRESSION_VALUE_AND_NVPMS; + } + else if ( gem.nullValuePropertyMappingStrategy().hasValue() && gem.defaultExpression().hasValue() ) { + message = Message.PROPERTYMAPPING_DEFAULT_EXPERSSION_AND_NVPMS; + } + else if ( gem.nullValuePropertyMappingStrategy().hasValue() + && gem.ignore().hasValue() && gem.ignore().getValue() ) { + message = Message.PROPERTYMAPPING_IGNORE_AND_NVPMS; + } + else if ( ".".equals( gem.target().get() ) && gem.ignore().hasValue() && gem.ignore().getValue() ) { + message = Message.PROPERTYMAPPING_TARGET_THIS_AND_IGNORE; + } + else if ( ".".equals( gem.target().get() ) && !gem.source().hasValue() ) { + message = Message.PROPERTYMAPPING_TARGET_THIS_NO_SOURCE; + } + if ( message == null ) { + return true; + } + else { + messager.printMessage( method, gem.mirror(), message ); + return false; + } } - /** - * @return the {@link Mapping}s configured for this method, keyed by target property name. Only for enum mapping - * methods a target will be mapped by several sources. TODO. Remove the value list when 2.0 - */ - public Map> getMappings() { - return mappings; + @SuppressWarnings("checkstyle:parameternumber") + private MappingOptions(String targetName, + Element element, + AnnotationValue targetAnnotationValue, + String sourceName, + AnnotationValue sourceAnnotationValue, + String constant, + String javaExpression, + String defaultJavaExpression, + String conditionJavaExpression, + String defaultValue, + boolean isIgnored, + FormattingParameters formattingParameters, + SelectionParameters selectionParameters, + Set dependsOn, + MappingGem mapping, + InheritContext inheritContext, + DelegatingOptions next + ) { + super( next ); + this.targetName = targetName; + this.element = element; + this.targetAnnotationValue = targetAnnotationValue; + this.sourceName = sourceName; + this.sourceAnnotationValue = sourceAnnotationValue; + this.constant = constant; + this.javaExpression = javaExpression; + this.defaultJavaExpression = defaultJavaExpression; + this.conditionJavaExpression = conditionJavaExpression; + this.defaultValue = defaultValue; + this.isIgnored = isIgnored; + this.formattingParameters = formattingParameters; + this.selectionParameters = selectionParameters; + this.dependsOn = dependsOn; + this.mapping = mapping; + this.inheritContext = inheritContext; } - /** - * Check there are nested target references for this mapping options. - * - * @return boolean, true if there are nested target references - */ - public boolean hasNestedTargetReferences() { - for ( List mappingList : mappings.values() ) { - for ( Mapping mapping : mappingList ) { - TargetReference targetReference = mapping.getTargetReference(); - if ( targetReference.isValid() && targetReference.getPropertyEntries().size() > 1 ) { - return true; - } - } + private static String getExpression(MappingGem mapping, ExecutableElement element, + FormattingMessager messager) { + if ( !mapping.expression().hasValue() ) { + return null; + } + + Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mapping.expression().get() ); + + if ( !javaExpressionMatcher.matches() ) { + messager.printMessage( + element, + mapping.mirror(), + mapping.expression().getAnnotationValue(), + Message.PROPERTYMAPPING_INVALID_EXPRESSION + ); + return null; } - return false; + + return javaExpressionMatcher.group( 1 ).trim(); } - /** - * - * @return all dependencies to other properties the contained mappings are dependent on - */ - public List collectNestedDependsOn() { + private static String getDefaultExpression(MappingGem mapping, ExecutableElement element, + FormattingMessager messager) { + if ( !mapping.defaultExpression().hasValue() ) { + return null; + } - List nestedDependsOn = new ArrayList(); - for ( List mappingList : mappings.values() ) { - for ( Mapping mapping : mappingList ) { - nestedDependsOn.addAll( mapping.getDependsOn() ); - } + Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mapping.defaultExpression().get() ); + + if ( !javaExpressionMatcher.matches() ) { + messager.printMessage( + element, + mapping.mirror(), + mapping.defaultExpression().getAnnotationValue(), + Message.PROPERTYMAPPING_INVALID_DEFAULT_EXPRESSION + ); + return null; } - return nestedDependsOn; + + return javaExpressionMatcher.group( 1 ).trim(); + } + + private static String getConditionExpression(MappingGem mapping, ExecutableElement element, + FormattingMessager messager) { + if ( !mapping.conditionExpression().hasValue() ) { + return null; + } + + Matcher javaExpressionMatcher = JAVA_EXPRESSION.matcher( mapping.conditionExpression().get() ); + + if ( !javaExpressionMatcher.matches() ) { + messager.printMessage( + element, + mapping.mirror(), + mapping.conditionExpression().getAnnotationValue(), + Message.PROPERTYMAPPING_INVALID_CONDITION_EXPRESSION + ); + return null; + } + + return javaExpressionMatcher.group( 1 ).trim(); + } + + public String getTargetName() { + return targetName; + } + + public AnnotationValue getTargetAnnotationValue() { + return targetAnnotationValue; } /** - * Initializes the underlying mappings with a new property. Specifically used in in combination with forged methods - * where the new parameter name needs to be established at a later moment. + * Returns the complete source name of this mapping, either a qualified (e.g. {@code parameter1.foo}) or + * unqualified (e.g. {@code foo}) property reference. * - * @param sourceParameter the new source parameter + * @return The complete source name of this mapping. */ - public void initWithParameter( Parameter sourceParameter ) { - for ( List mappingList : mappings.values() ) { - for ( Mapping mapping : mappingList ) { - mapping.init( sourceParameter ); - } - } + public String getSourceName() { + return sourceName; } - public IterableMapping getIterableMapping() { - return iterableMapping; + public AnnotationValue getSourceAnnotationValue() { + return sourceAnnotationValue; } - public MapMapping getMapMapping() { - return mapMapping; + public String getConstant() { + return constant; } - public BeanMapping getBeanMapping() { - return beanMapping; + public String getJavaExpression() { + return javaExpression; } - public List getValueMappings() { - return valueMappings; + public String getDefaultJavaExpression() { + return defaultJavaExpression; } - public void setMappings(Map> mappings) { - this.mappings = mappings; + public String getConditionJavaExpression() { + return conditionJavaExpression; } - public void setIterableMapping(IterableMapping iterableMapping) { - this.iterableMapping = iterableMapping; + public String getDefaultValue() { + return defaultValue; } - public void setMapMapping(MapMapping mapMapping) { - this.mapMapping = mapMapping; + public FormattingParameters getFormattingParameters() { + return formattingParameters; } - public void setBeanMapping(BeanMapping beanMapping) { - this.beanMapping = beanMapping; + public SelectionParameters getSelectionParameters() { + return selectionParameters; } - public void setValueMappings(List valueMappings) { - this.valueMappings = valueMappings; + public boolean isIgnored() { + return isIgnored; + } + + public AnnotationMirror getMirror() { + return Optional.ofNullable( mapping ).map( MappingGem::mirror ).orElse( null ); + } + + public Element getElement() { + return element; + } + + public AnnotationValue getDependsOnAnnotationValue() { + return Optional.ofNullable( mapping ) + .map( MappingGem::dependsOn ) + .map( GemValue::getAnnotationValue ) + .orElse( null ); + } + + public Set getDependsOn() { + return dependsOn; + } + + public InheritContext getInheritContext() { + return inheritContext; + } + + @Override + public NullValueCheckStrategyGem getNullValueCheckStrategy() { + return Optional.ofNullable( mapping ).map( MappingGem::nullValueCheckStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValueCheckStrategyGem::valueOf ) + .orElse( next().getNullValueCheckStrategy() ); + } + + @Override + public NullValuePropertyMappingStrategyGem getNullValuePropertyMappingStrategy() { + return Optional.ofNullable( mapping ).map( MappingGem::nullValuePropertyMappingStrategy ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( NullValuePropertyMappingStrategyGem::valueOf ) + .orElse( next().getNullValuePropertyMappingStrategy() ); + } + + @Override + public MappingControl getMappingControl(ElementUtils elementUtils) { + return Optional.ofNullable( mapping ).map( MappingGem::mappingControl ) + .filter( GemValue::hasValue ) + .map( GemValue::getValue ) + .map( mc -> MappingControl.fromTypeMirror( mc, elementUtils ) ) + .orElse( next().getMappingControl( elementUtils ) ); } /** - * @return the {@code true}, iff the options have been fully initialized by applying all available inheritance - * options + * Mapping can only be inversed if the source was not a constant nor an expression + * + * @return true when the above applies */ - public boolean isFullyInitialized() { - return fullyInitialized; + public boolean canInverse() { + return constant == null && javaExpression == null; } - public void markAsFullyInitialized() { - this.fullyInitialized = true; + public MappingOptions copyForInverseInheritance(SourceMethod templateMethod, + BeanMappingOptions beanMappingOptions ) { + + MappingOptions mappingOptions = new MappingOptions( + sourceName != null ? sourceName : targetName, + templateMethod.getExecutable(), + targetAnnotationValue, + sourceName != null ? targetName : null, + sourceAnnotationValue, + null, // constant + null, // expression + null, // defaultExpression + null, // conditionExpression + null, + isIgnored, + formattingParameters, + selectionParameters, + Collections.emptySet(), + mapping, + new InheritContext( true, false, templateMethod ), + beanMappingOptions + ); + return mappingOptions; + } /** - * Merges in all the mapping options configured, giving the already defined options precedence. + * Creates a copy of this mapping + * + * @param templateMethod the template method for the inheritance + * @param beanMappingOptions the bean mapping options * - * @param inherited the options to inherit, may be {@code null} - * @param isInverse if {@code true}, the specified options are from an inverse method - * @param method the source method - * @param messager the messager - * @param typeFactory the type factory - * @param accessorNaming the accessor naming utils + * @return the copy */ - public void applyInheritedOptions(MappingOptions inherited, boolean isInverse, SourceMethod method, - FormattingMessager messager, TypeFactory typeFactory, - AccessorNamingUtils accessorNaming) { - if ( null != inherited ) { - if ( getIterableMapping() == null ) { - if ( inherited.getIterableMapping() != null ) { - setIterableMapping( inherited.getIterableMapping() ); - } - } - - if ( getMapMapping() == null ) { - if ( inherited.getMapMapping() != null ) { - setMapMapping( inherited.getMapMapping() ); - } - } - - if ( getBeanMapping() == null ) { - if ( inherited.getBeanMapping() != null ) { - setBeanMapping( BeanMapping.forInheritance( inherited.getBeanMapping() ) ); - } - } - - if ( getValueMappings() == null ) { - if ( inherited.getValueMappings() != null ) { - // there were no mappings, so the inherited mappings are the new ones - setValueMappings( inherited.getValueMappings() ); - } - else { - setValueMappings( Collections.emptyList() ); - } - } - else { - if ( inherited.getValueMappings() != null ) { - // iff there are also inherited mappings, we reverse and add them. - for ( ValueMapping inheritedValueMapping : inherited.getValueMappings() ) { - ValueMapping valueMapping = isInverse ? inheritedValueMapping.reverse() : inheritedValueMapping; - if ( valueMapping != null - && !getValueMappings().contains( valueMapping ) ) { - getValueMappings().add( valueMapping ); - } - } - } - - } - - Map> newMappings = new HashMap>(); - - for ( List lmappings : inherited.getMappings().values() ) { - for ( Mapping mapping : lmappings ) { - if ( isInverse ) { - mapping = mapping.reverse( method, messager, typeFactory, accessorNaming ); - } - - if ( mapping != null ) { - List mappingsOfProperty = newMappings.get( mapping.getTargetName() ); - if ( mappingsOfProperty == null ) { - mappingsOfProperty = new ArrayList(); - newMappings.put( mapping.getTargetName(), mappingsOfProperty ); - } - - mappingsOfProperty.add( mapping.copyForInheritanceTo( method ) ); - } - } - } - - - // now add all of its own mappings - newMappings.putAll( getMappings() ); - - // filter new mappings - filterNestedTargetIgnores( newMappings ); - - setMappings( newMappings ); - } - } - - public void applyIgnoreAll(MappingOptions inherited, SourceMethod method, FormattingMessager messager, - TypeFactory typeFactory, AccessorNamingUtils accessorNaming) { - CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy(); - Type writeType = method.getResultType(); - if ( !method.isUpdateMethod() ) { - writeType = writeType.getEffectiveType(); - } - Map writeAccessors = writeType.getPropertyWriteAccessors( cms ); - List mappedPropertyNames = new ArrayList(); - for ( String targetMappingName : mappings.keySet() ) { - mappedPropertyNames.add( targetMappingName.split( "\\." )[0] ); - } - for ( String targetPropertyName : writeAccessors.keySet() ) { - if ( !mappedPropertyNames.contains( targetPropertyName ) ) { - Mapping mapping = Mapping.forIgnore( targetPropertyName ); - mapping.init( method, messager, typeFactory, accessorNaming ); - mappings.put( targetPropertyName, Arrays.asList( mapping ) ); - } - } - } - - private void filterNestedTargetIgnores( Map> mappings) { - - // collect all properties to ignore, and safe their target name ( == same name as first ref target property) - Set ignored = new HashSet(); - for ( Map.Entry> mappingEntry : mappings.entrySet() ) { - Mapping mapping = first( mappingEntry.getValue() ); // list only used for deprecated enums mapping - if ( mapping.isIgnored() && mapping.getTargetReference().isValid() ) { - ignored.add( mapping.getTargetName() ); - } - } + public MappingOptions copyForForwardInheritance(SourceMethod templateMethod, + BeanMappingOptions beanMappingOptions ) { + MappingOptions mappingOptions = new MappingOptions( + targetName, + templateMethod.getExecutable(), + targetAnnotationValue, + sourceName, + sourceAnnotationValue, + constant, + javaExpression, + defaultJavaExpression, + conditionJavaExpression, + defaultValue, + isIgnored, + formattingParameters, + selectionParameters, + dependsOn, + mapping, + new InheritContext( false, true, templateMethod ), + beanMappingOptions + ); + return mappingOptions; + } - // collect all entries to remove (avoid concurrent modification) - Set toBeRemoved = new HashSet(); - for ( Map.Entry> mappingEntry : mappings.entrySet() ) { - Mapping mapping = first( mappingEntry.getValue() ); // list only used for deprecated enums mapping - TargetReference targetReference = mapping.getTargetReference(); - if ( targetReference.isValid() - && targetReference.getPropertyEntries().size() > 1 - && ignored.contains( first( targetReference.getPropertyEntries() ).getName() ) ) { - toBeRemoved.add( mappingEntry.getKey() ); - } + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( ".".equals( this.targetName ) ) { + // target this will never be equal to any other target this or any other. + return false; } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + MappingOptions mapping = (MappingOptions) o; + return targetName.equals( mapping.targetName ); + } - // finall remove all duplicates - mappings.keySet().removeAll( toBeRemoved ); + @Override + public int hashCode() { + return Objects.hash( targetName ); + } + @Override + public String toString() { + return "Mapping {" + + "\n sourceName='" + sourceName + "\'," + + "\n targetName='" + targetName + "\'," + + "\n}"; } - public boolean isRestrictToDefinedMappings() { - return restrictToDefinedMappings; + @Override + public boolean hasAnnotation() { + return mapping != null; } } + diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java index 9f93205a12..d9c9ce41fc 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/Method.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; import java.util.List; - import javax.lang.model.element.ExecutableElement; import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod; -import org.mapstruct.ap.internal.util.MapperConfiguration; /** * This interface makes available common method properties and a matching method There are 2 known implementors: @@ -98,7 +83,7 @@ public interface Method { Parameter getMappingTargetParameter(); /** - * Returns whether the meethod is designated as bean factory for + * Returns whether the method is designated as bean factory for * mapping target {@link org.mapstruct.ObjectFactory } * * @return true if it is a target bean factory. @@ -112,7 +97,6 @@ public interface Method { */ Parameter getTargetTypeParameter(); - /** * Returns the {@link Accessibility} of this method. * @@ -142,7 +126,6 @@ public interface Method { */ Type getResultType(); - /** * * @return the names of the parameters of this mapping method @@ -178,12 +161,6 @@ public interface Method { */ Type getDefiningType(); - /** - * - * @return the mapper config when this method needs to be implemented - */ - MapperConfiguration getMapperConfiguration(); - /** * @return {@code true}, if the method represents a mapping lifecycle callback (Before/After mapping method) */ @@ -199,5 +176,28 @@ public interface Method { * * @return the mapping options for this method */ - MappingOptions getMappingOptions(); + MappingMethodOptions getOptions(); + + default ConditionMethodOptions getConditionOptions() { + return ConditionMethodOptions.empty(); + } + + /** + * @return the first source type, intended for mapping methods from single source to target + */ + default Type getMappingSourceType() { + return getSourceParameters().get( 0 ).getType(); + } + + /** + * @return the short name for error messages when verbose, full name when not + */ + String describe(); + + /** + * Returns the formal type parameters of this method in declaration order. + * + * @return the formal type parameters, or an empty list if there are none + */ + List getTypeParameters(); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MethodMatcher.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MethodMatcher.java index 91cc151064..c62012472c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/MethodMatcher.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/MethodMatcher.java @@ -1,42 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.TypeParameterElement; -import javax.lang.model.type.ArrayType; +import java.util.stream.Collectors; import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.PrimitiveType; -import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.type.TypeVariable; -import javax.lang.model.type.WildcardType; -import javax.lang.model.util.SimpleTypeVisitor6; -import javax.lang.model.util.Types; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.TypeUtils; /** * SourceMethodMatcher $8.4 of the JavaLanguage specification describes a method body as such: @@ -66,10 +46,10 @@ public class MethodMatcher { private final SourceMethod candidateMethod; - private final Types typeUtils; + private final TypeUtils typeUtils; private final TypeFactory typeFactory; - MethodMatcher(Types typeUtils, TypeFactory typeFactory, SourceMethod candidateMethod) { + MethodMatcher(TypeUtils typeUtils, TypeFactory typeFactory, SourceMethod candidateMethod) { this.typeUtils = typeUtils; this.candidateMethod = candidateMethod; this.typeFactory = typeFactory; @@ -79,345 +59,363 @@ public class MethodMatcher { * Whether the given source and target types are matched by this matcher's candidate method. * * @param sourceTypes the source types - * @param resultType the target type + * @param targetType the target type * @return {@code true} when both, source type and target types match the signature of this matcher's method; * {@code false} otherwise. */ - boolean matches(List sourceTypes, Type resultType) { - - // check & collect generic types. - Map genericTypesMap = new HashMap(); + boolean matches(List sourceTypes, Type targetType) { - if ( candidateMethod.getParameters().size() == sourceTypes.size() ) { - int i = 0; - for ( Parameter candidateParam : candidateMethod.getParameters() ) { - Type sourceType = sourceTypes.get( i++ ); - if ( sourceType == null - || !matchSourceType( sourceType, candidateParam.getType(), genericTypesMap ) ) { - return false; - } - } - } - else { + GenericAnalyser analyser = + new GenericAnalyser( typeFactory, typeUtils, candidateMethod, sourceTypes, targetType ); + if ( !analyser.lineUp() ) { return false; } - // check if the method matches the proper result type to construct - Parameter targetTypeParameter = candidateMethod.getTargetTypeParameter(); - if ( targetTypeParameter != null ) { - Type returnClassType = typeFactory.classTypeOf( resultType ); - if ( !matchSourceType( returnClassType, targetTypeParameter.getType(), genericTypesMap ) ) { + for ( int i = 0; i < sourceTypes.size(); i++ ) { + Type candidateSourceParType = analyser.candidateParTypes.get( i ); + if ( !sourceTypes.get( i ).isAssignableTo( candidateSourceParType ) + || isPrimitiveToObject( sourceTypes.get( i ), candidateSourceParType ) ) { return false; } } - - // check result type - if ( !matchResultType( resultType, genericTypesMap ) ) { - return false; - } - - // check if all type parameters are indeed mapped - if ( candidateMethod.getExecutable().getTypeParameters().size() != genericTypesMap.size() ) { - return false; - } - - // check if all entries are in the bounds - for ( Map.Entry entry : genericTypesMap.entrySet() ) { - if ( !isWithinBounds( entry.getValue(), getTypeParamFromCandidate( entry.getKey() ) ) ) { - // checks if the found Type is in bounds of the TypeParameters bounds. + // TODO: TargetType checking should not be part of method selection, it should be in checking the annotation + // (the relation target / target type, target type being a class) + + if ( !analyser.candidateReturnType.isVoid() ) { + if ( targetType.isPrimitive() ) { + // If the target type is primitive + // then we are going to check if its boxed equivalent + // is assignable to the candidate return type + // This is done because primitives can be assigned from their own narrower counterparts + // directly without any casting. + // e.g. a Long is assignable to a primitive double + // However, in order not to lose information we are not going to allow this + return targetType.getBoxedEquivalent() + .isAssignableTo( analyser.candidateReturnType.getBoxedEquivalent() ); + } + if ( !( analyser.candidateReturnType.isAssignableTo( targetType ) ) ) { return false; } } + return true; } - private boolean matchSourceType(Type sourceType, - Type candidateSourceType, - Map genericTypesMap) { - - if ( !isJavaLangObject( candidateSourceType.getTypeMirror() ) ) { - TypeMatcher parameterMatcher = new TypeMatcher( Assignability.VISITED_ASSIGNABLE_FROM, genericTypesMap ); - if ( !parameterMatcher.visit( candidateSourceType.getTypeMirror(), sourceType.getTypeMirror() ) ) { - if ( sourceType.isPrimitive() ) { - // the candidate source is primitive, so promote to its boxed type and check again (autobox) - TypeMirror boxedType = typeUtils.boxedClass( (PrimitiveType) sourceType.getTypeMirror() ).asType(); - if ( !parameterMatcher.visit( candidateSourceType.getTypeMirror(), boxedType ) ) { - return false; - } - } - else { - // NOTE: unboxing is deliberately not considered here. This should be handled via type-conversion - // (for NPE safety). - return false; - } - } + /** + * Primitive to Object (Boxed Type) should be handled by a type conversion rather than a direct mapping + * Direct mapping runs the risk of null pointer exceptions: e.g. in the assignment of Integer to int, Integer + * can be null. + * + * @param type the type to be assigned + * @param isAssignableTo the type to which @param type should be assignable to + * @return true if isAssignable is a primitive type and type is an object + */ + private boolean isPrimitiveToObject( Type type, Type isAssignableTo ) { + if ( isAssignableTo.isPrimitive() ) { + return !type.isPrimitive(); } - return true; + return false; } - private boolean matchResultType(Type resultType, Map genericTypesMap) { + private static class GenericAnalyser { + + private TypeFactory typeFactory; + private TypeUtils typeUtils; + private Method candidateMethod; + private List sourceTypes; + private Type targetType; + + GenericAnalyser(TypeFactory typeFactory, TypeUtils typeUtils, Method candidateMethod, + List sourceTypes, Type targetType) { + this.typeFactory = typeFactory; + this.typeUtils = typeUtils; + this.candidateMethod = candidateMethod; + this.sourceTypes = sourceTypes; + this.targetType = targetType; + } - Type candidateResultType = candidateMethod.getResultType(); + Type candidateReturnType = null; + List candidateParTypes; - if ( !isJavaLangObject( candidateResultType.getTypeMirror() ) && !candidateResultType.isVoid() ) { + private boolean lineUp() { - final Assignability visitedAssignability; - if ( candidateMethod.getReturnType().isVoid() ) { - // for void-methods, the result-type of the candidate needs to be assignable from the given result type - visitedAssignability = Assignability.VISITED_ASSIGNABLE_FROM; - } - else { - // for non-void methods, the result-type of the candidate needs to be assignable to the given result - // type - visitedAssignability = Assignability.VISITED_ASSIGNABLE_TO; + if ( candidateMethod.getParameters().size() != sourceTypes.size() ) { + return false; } - TypeMatcher returnTypeMatcher = new TypeMatcher( visitedAssignability, genericTypesMap ); - if ( !returnTypeMatcher.visit( candidateResultType.getTypeMirror(), resultType.getTypeMirror() ) ) { - if ( resultType.isPrimitive() ) { - TypeMirror boxedType = typeUtils.boxedClass( (PrimitiveType) resultType.getTypeMirror() ).asType(); - TypeMatcher boxedReturnTypeMatcher = - new TypeMatcher( visitedAssignability, genericTypesMap ); + if ( !candidateMethod.getTypeParameters().isEmpty() ) { - if ( !boxedReturnTypeMatcher.visit( candidateResultType.getTypeMirror(), boxedType ) ) { - return false; + this.candidateParTypes = new ArrayList<>(); + + // Per generic method parameter the associated type variable candidates + Map methodParCandidates = new HashMap<>(); + + // Get candidates + boolean success = getCandidates( methodParCandidates ); + if ( !success ) { + return false; + } + + // Check type bounds + boolean withinBounds = candidatesWithinBounds( methodParCandidates ); + if ( !withinBounds ) { + return false; + } + + // Represent result as map. + Map resolvedPairs = new HashMap<>(); + for ( TypeVarCandidate candidate : methodParCandidates.values() ) { + for ( Type.ResolvedPair pair : candidate.pairs ) { + resolvedPairs.put( pair.getParameter(), pair.getMatch() ); } } - else if ( candidateResultType.getTypeMirror().getKind().isPrimitive() ) { - TypeMirror boxedCandidateReturnType = - typeUtils.boxedClass( (PrimitiveType) candidateResultType.getTypeMirror() ).asType(); - TypeMatcher boxedReturnTypeMatcher = - new TypeMatcher( visitedAssignability, genericTypesMap ); - if ( !boxedReturnTypeMatcher.visit( boxedCandidateReturnType, resultType.getTypeMirror() ) ) { + // Resolve parameters and return type by using the found candidates + int nrOfMethodPars = candidateMethod.getParameters().size(); + for ( int i = 0; i < nrOfMethodPars; i++ ) { + Type candidateType = resolve( candidateMethod.getParameters().get( i ).getType(), resolvedPairs ); + if ( candidateType == null ) { return false; } + this.candidateParTypes.add( candidateType ); } + if ( !candidateMethod.getReturnType().isVoid() ) { + this.candidateReturnType = resolve( candidateMethod.getReturnType(), resolvedPairs ); + if ( this.candidateReturnType == null ) { + return false; + } + } else { - return false; + this.candidateReturnType = candidateMethod.getReturnType(); } } + else { + this.candidateParTypes = candidateMethod.getParameters().stream() + .map( Parameter::getType ) + .collect( Collectors.toList() ); + this.candidateReturnType = candidateMethod.getReturnType(); + } + return true; } - return true; - } - - /** - * @param type the type - * @return {@code true}, if the type represents java.lang.Object - */ - private boolean isJavaLangObject(TypeMirror type) { - return type.getKind() == TypeKind.DECLARED - && ( (TypeElement) ( (DeclaredType) type ).asElement() ).getQualifiedName().contentEquals( - Object.class.getName() ); - } - - private enum Assignability { - VISITED_ASSIGNABLE_FROM, VISITED_ASSIGNABLE_TO; - Assignability invert() { - return this == VISITED_ASSIGNABLE_FROM - ? VISITED_ASSIGNABLE_TO - : VISITED_ASSIGNABLE_FROM; + /** + * {@code T map( U in ) } + * + * Resolves all method generic parameter candidates + * + * @param methodParCandidates Map, keyed by the method generic parameter (T, U extends Number), with their + * respective candidates + * + * @return false no match or conflict has been found * + */ + boolean getCandidates( Map methodParCandidates) { + + int nrOfMethodPars = candidateMethod.getParameters().size(); + Type returnType = candidateMethod.getReturnType(); + + for ( int i = 0; i < nrOfMethodPars; i++ ) { + Type sourceType = sourceTypes.get( i ); + Parameter par = candidateMethod.getParameters().get( i ); + Type parType = par.getType(); + boolean success = getCandidates( parType, sourceType, methodParCandidates ); + if ( !success ) { + return false; + } + } + if ( !returnType.isVoid() ) { + boolean success = getCandidates( returnType, targetType, methodParCandidates ); + if ( !success ) { + return false; + } + } + return true; } - } - private class TypeMatcher extends SimpleTypeVisitor6 { - private final Assignability assignability; - private final Map genericTypesMap; - private final TypeMatcher inverse; + /** + * @param aCandidateMethodType parameter type or return type from candidate method + * @param matchingType source type / target type to match + * @param candidates Map, keyed by the method generic parameter, with the candidates + * + * @return false no match or conflict has been found + */ + boolean getCandidates(Type aCandidateMethodType, Type matchingType, Map candidates ) { + + if ( !( aCandidateMethodType.isTypeVar() + || aCandidateMethodType.isArrayTypeVar() + || aCandidateMethodType.isWildCardBoundByTypeVar() + || hasGenericTypeParameters( aCandidateMethodType ) ) ) { + // the typeFromCandidateMethod is not a generic (parameterized) type + return true; + } - TypeMatcher(Assignability assignability, Map genericTypesMap) { - super( Boolean.FALSE ); // default value - this.assignability = assignability; - this.genericTypesMap = genericTypesMap; - this.inverse = new TypeMatcher( this, genericTypesMap ); - } + boolean foundAMatch = false; - TypeMatcher(TypeMatcher inverse, Map genericTypesMap) { - super( Boolean.FALSE ); // default value - this.assignability = inverse.assignability.invert(); - this.genericTypesMap = genericTypesMap; - this.inverse = inverse; - } + for ( Type mthdParType : candidateMethod.getTypeParameters() ) { - @Override - public Boolean visitPrimitive(PrimitiveType t, TypeMirror p) { - return typeUtils.isSameType( t, p ); - } + // typeFromCandidateMethod itself is a generic type, e.g. String method( T par ); + // typeFromCandidateMethod is a generic arrayType e.g. String method( T[] par ); + // typeFromCandidateMethod is embedded in another type e.g. String method( Callable par ); + // typeFromCandidateMethod is a wildcard, bounded by a typeVar + // e.g. String method( List in ) - @Override - public Boolean visitArray(ArrayType t, TypeMirror p) { + Type.ResolvedPair resolved = mthdParType.resolveParameterToType( matchingType, aCandidateMethodType ); + if ( resolved.getMatch() == null ) { + // we should be dealing with something containing a type parameter at this point. This is + // covered with the checks above. Therefore resolved itself cannot be null. + // If there is no match here, continue with the next candidate, perhaps there will a match with + // the next method type parameter + continue; + } - if ( p.getKind().equals( TypeKind.ARRAY ) ) { - return t.getComponentType().accept( this, ( (ArrayType) p ).getComponentType() ); - } - else { - return Boolean.FALSE; - } - } + foundAMatch = true; // there is a rare case where we do not arrive here at all. - @Override - public Boolean visitDeclared(DeclaredType t, TypeMirror p) { - // its a match when: 1) same kind of type, name is equals, nr of type args are the same - // (type args are checked later). - if ( p.getKind() == TypeKind.DECLARED ) { - DeclaredType t1 = (DeclaredType) p; - if ( assignabilityMatches( t, t1 ) - && t.getTypeArguments().size() == t1.getTypeArguments().size() ) { - for ( int i = 0; i < t.getTypeArguments().size(); i++ ) { - if ( !visit( t.getTypeArguments().get( i ), t1.getTypeArguments().get( i ) ) ) { - return Boolean.FALSE; - } + // resolved something at this point, a candidate can be fetched or created + TypeVarCandidate typeVarCandidate; + if ( candidates.containsKey( mthdParType ) ) { + typeVarCandidate = candidates.get( mthdParType ); + } + else { + // add a new type + typeVarCandidate = new TypeVarCandidate( ); + candidates.put( mthdParType, typeVarCandidate ); + } + + // check what we've resolved + if ( resolved.getParameter().isTypeVar() ) { + // it might be already set, but we just checked if its an equivalent type + if ( typeVarCandidate.match == null ) { + typeVarCandidate.match = resolved.getMatch(); + typeVarCandidate.pairs.add( resolved ); + } + else if ( !areEquivalent( resolved.getMatch(), typeVarCandidate.match ) ) { + // type has been resolved twice, but with a different candidate (conflict). Stop + return false; } - return Boolean.TRUE; + + } + else if ( resolved.getParameter().isArrayTypeVar() + && resolved.getParameter().getComponentType().isAssignableTo( mthdParType ) ) { + // e.g. T map( List in ), the match for T should be assignable + // to the parameter T extends Number + typeVarCandidate.pairs.add( resolved ); + } + else if ( resolved.getParameter().isWildCardBoundByTypeVar() + && resolved.getParameter().getTypeBound().isAssignableTo( mthdParType ) ) { + // e.g. T map( List in ), the match for ? super T should be assignable + // to the parameter T extends Number + typeVarCandidate.pairs.add( resolved ); } else { - return Boolean.FALSE; + // none of the above + return false; } } - else if ( p.getKind() == TypeKind.WILDCARD ) { - return inverse.visit( p, t ); // inverse, as we switch the params - } - else { - return Boolean.FALSE; - } + return foundAMatch; } - private boolean assignabilityMatches(DeclaredType visited, DeclaredType param) { - if ( assignability == Assignability.VISITED_ASSIGNABLE_TO ) { - return typeUtils.isAssignable( toRawType( visited ), toRawType( param ) ); - } - else { - return typeUtils.isAssignable( toRawType( param ), toRawType( visited ) ); + /** + * Checks whether all found candidates are within the bounds of the method type var. For instance + * @ U map( T in ). Note that only the relation between the + * match for U and Callable are checked. Not the correct parameter. + * + * @param methodParCandidates + * + * @return true when all within bounds. + */ + private boolean candidatesWithinBounds(Map methodParCandidates ) { + for ( Map.Entry entry : methodParCandidates.entrySet() ) { + for ( Type bound : entry.getKey().getTypeBounds() ) { + for ( Type.ResolvedPair pair : entry.getValue().pairs ) { + if ( entry.getKey().hasUpperBound() ) { + if ( !pair.getMatch().asRawType().isAssignableTo( bound.asRawType() ) ) { + return false; + } + } + else { + // lower bound + if ( !bound.asRawType().isAssignableTo( pair.getMatch().asRawType() ) ) { + return false; + } + } + } + } } + return true; } - private DeclaredType toRawType(DeclaredType t) { - return typeUtils.getDeclaredType( (TypeElement) t.asElement() ); - } - - @Override - public Boolean visitTypeVariable(TypeVariable t, TypeMirror p) { - if ( genericTypesMap.containsKey( t ) ) { - // when already found, the same mapping should apply - TypeMirror p1 = genericTypesMap.get( t ); - return typeUtils.isSameType( p, p1 ); - } - else { - // check if types are in bound - TypeMirror lowerBound = t.getLowerBound(); - TypeMirror upperBound = t.getUpperBound(); - if ( ( isNullType( lowerBound ) || typeUtils.isSubtype( lowerBound, p ) ) - && ( isNullType( upperBound ) || typeUtils.isSubtype( p, upperBound ) ) ) { - genericTypesMap.put( t, p ); - return Boolean.TRUE; + private boolean hasGenericTypeParameters(Type typeFromCandidateMethod) { + for ( Type typeParam : typeFromCandidateMethod.getTypeParameters() ) { + if ( typeParam.isTypeVar() || typeParam.isWildCardBoundByTypeVar() || typeParam.isArrayTypeVar() ) { + return true; } else { - return Boolean.FALSE; + if ( hasGenericTypeParameters( typeParam ) ) { + return true; + } } } + return false; } - private boolean isNullType(TypeMirror type) { - return type == null || type.getKind() == TypeKind.NULL; - } - - @Override - public Boolean visitWildcard(WildcardType t, TypeMirror p) { - - // check extends bound - TypeMirror extendsBound = t.getExtendsBound(); - if ( !isNullType( extendsBound ) ) { - switch ( extendsBound.getKind() ) { - case DECLARED: - // for example method: String method(? extends String) - // isSubType checks range [subtype, type], e.g. isSubtype [Object, String]==true - return visit( extendsBound, p ); - - case TYPEVAR: - // for example method: T method(? extends T) - // this can be done the directly by checking: ? extends String & Serializable - // this checks the part? - return isWithinBounds( p, getTypeParamFromCandidate( extendsBound ) ); - - default: - // does this situation occur? - return Boolean.FALSE; - } + private Type resolve( Type typeFromCandidateMethod, Map pairs ) { + if ( typeFromCandidateMethod.isTypeVar() || typeFromCandidateMethod.isArrayTypeVar() ) { + return pairs.get( typeFromCandidateMethod ); } - - // check super bound - TypeMirror superBound = t.getSuperBound(); - if ( !isNullType( superBound ) ) { - switch ( superBound.getKind() ) { - case DECLARED: - // for example method: String method(? super String) - // to check super type, we can simply reverse the argument, but that would initially yield - // a result: T method(? super T) - if ( !isWithinBounds( p, typeParameter ) ) { - // this checks the part? - return Boolean.FALSE; + else if ( hasGenericTypeParameters( typeFromCandidateMethod ) ) { + TypeMirror[] typeArgs = new TypeMirror[ typeFromCandidateMethod.getTypeParameters().size() ]; + for ( int i = 0; i < typeFromCandidateMethod.getTypeParameters().size(); i++ ) { + Type typeFromCandidateMethodTypeParameter = typeFromCandidateMethod.getTypeParameters().get( i ); + if ( hasGenericTypeParameters( typeFromCandidateMethodTypeParameter ) ) { + // nested type var, lets resolve some more (recur) + Type matchingType = resolve( typeFromCandidateMethodTypeParameter, pairs ); + if ( matchingType == null ) { + // something went wrong + return null; + } + typeArgs[i] = matchingType.getTypeMirror(); + } + else if ( typeFromCandidateMethodTypeParameter.isWildCardBoundByTypeVar() + || typeFromCandidateMethodTypeParameter.isTypeVar() + || typeFromCandidateMethodTypeParameter.isArrayTypeVar() + ) { + Type matchingType = pairs.get( typeFromCandidateMethodTypeParameter ); + if ( matchingType == null ) { + // something went wrong + return null; } - // now, it becomes a bit more hairy. We have the relation (? super T). From T we know that - // it is a subclass of String & Serializable. However, The Java Language Secification, - // Chapter 4.4, states that a bound is either: 'A type variable-', 'A class-' or 'An - // interface-' type followed by further interface types. So we must compare with the first - // argument in the Expression String & Serializable & ..., so, in this case String. - // to check super type, we can simply reverse the argument, but that would initially yield - // a result: ), String is not a type var + typeArgs[i] = typeFromCandidateMethodTypeParameter.getTypeMirror(); + } } + DeclaredType typeArg = typeUtils.getDeclaredType( typeFromCandidateMethod.getTypeElement(), typeArgs ); + return typeFactory.getType( typeArg ); + } + else { + // its not a type var or generic parameterized (e.g. just a plain type) + return typeFromCandidateMethod; } - return Boolean.TRUE; } - } - - /** - * Looks through the list of type parameters of the candidate method for a match - * - * @param t type parameter to match - * - * @return matching type parameter - */ - private TypeParameterElement getTypeParamFromCandidate(TypeMirror t) { - for ( TypeParameterElement candidateTypeParam : candidateMethod.getExecutable().getTypeParameters() ) { - if ( typeUtils.isSameType( candidateTypeParam.asType(), t ) ) { - return candidateTypeParam; + boolean areEquivalent( Type a, Type b ) { + if ( a == null || b == null ) { + return false; } + return a.getBoxedEquivalent().equals( b.getBoxedEquivalent() ); } - return null; } - /** - * checks whether a type t is in bounds of the typeParameter tpe - * - * @return true if within bounds - */ - private boolean isWithinBounds(TypeMirror t, TypeParameterElement tpe) { - List bounds = tpe != null ? tpe.getBounds() : null; - if ( t != null && bounds != null ) { - for ( TypeMirror bound : bounds ) { - if ( !( bound.getKind() == TypeKind.DECLARED && typeUtils.isSubtype( t, bound ) ) ) { - return false; - } - } - return true; - } - return false; + private static class TypeVarCandidate { + + private Type match; + private List pairs = new ArrayList<>(); + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ParameterProvidedMethods.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ParameterProvidedMethods.java index 79a0aa8d40..6552e43505 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ParameterProvidedMethods.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ParameterProvidedMethods.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; @@ -36,14 +23,14 @@ */ public class ParameterProvidedMethods { private static final ParameterProvidedMethods EMPTY = - new ParameterProvidedMethods( Collections.> emptyMap() ); + new ParameterProvidedMethods( Collections.emptyMap() ); private final Map> parameterToProvidedMethods; private final Map methodToProvidingParameter; private ParameterProvidedMethods(Map> parameterToProvidedMethods) { this.parameterToProvidedMethods = parameterToProvidedMethods; - this.methodToProvidingParameter = new IdentityHashMap(); + this.methodToProvidingParameter = new IdentityHashMap<>(); for ( Entry> entry : parameterToProvidedMethods.entrySet() ) { for ( SourceMethod method : entry.getValue() ) { methodToProvidingParameter.put( method, entry.getKey() ); @@ -57,7 +44,7 @@ private ParameterProvidedMethods(Map> parameterToP * methods of each parameter ordered based on their definition in that parameter's type. */ public List getAllProvidedMethodsInParameterOrder(List orderedParameters) { - List result = new ArrayList(); + List result = new ArrayList<>(); for ( Parameter parameter : orderedParameters ) { List methods = parameterToProvidedMethods.get( parameter ); @@ -95,7 +82,7 @@ public static ParameterProvidedMethods empty() { public static class Builder { private Map> contextProvidedMethods = - new HashMap>(); + new HashMap<>(); private Builder() { } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/PropertyEntry.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/PropertyEntry.java deleted file mode 100644 index 4e189015c4..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/PropertyEntry.java +++ /dev/null @@ -1,149 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import java.util.Arrays; - -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.util.Strings; -import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; - - -/** - * A PropertyEntry contains information on the name, readAccessor (for source), readAccessor and writeAccessor - * (for targets) and return type of a property. - */ -public class PropertyEntry { - - private final String[] fullName; - private final Accessor readAccessor; - private final Accessor writeAccessor; - private final ExecutableElementAccessor presenceChecker; - private final Type type; - - /** - * Constructor used to create {@link TargetReference} property entries from a mapping - * - * @param fullName - * @param readAccessor - * @param writeAccessor - * @param type - */ - private PropertyEntry(String[] fullName, Accessor readAccessor, Accessor writeAccessor, - ExecutableElementAccessor presenceChecker, Type type) { - this.fullName = fullName; - this.readAccessor = readAccessor; - this.writeAccessor = writeAccessor; - this.presenceChecker = presenceChecker; - this.type = type; - } - - /** - * Constructor used to create {@link TargetReference} property entries - * - * @param fullName name of the property (dot separated) - * @param readAccessor its read accessor - * @param writeAccessor its write accessor - * @param type type of the property - * @return the property entry for given parameters. - */ - public static PropertyEntry forTargetReference(String[] fullName, Accessor readAccessor, - Accessor writeAccessor, Type type) { - return new PropertyEntry( fullName, readAccessor, writeAccessor, null, type ); - } - - /** - * Constructor used to create {@link SourceReference} property entries from a mapping - * - * @param name name of the property (dot separated) - * @param readAccessor its read accessor - * @param presenceChecker its presence Checker - * @param type type of the property - * @return the property entry for given parameters. - */ - public static PropertyEntry forSourceReference(String name, Accessor readAccessor, - ExecutableElementAccessor presenceChecker, Type type) { - return new PropertyEntry( new String[]{name}, readAccessor, null, presenceChecker, type ); - } - - public String getName() { - return fullName[fullName.length - 1]; - } - - public Accessor getReadAccessor() { - return readAccessor; - } - - public Accessor getWriteAccessor() { - return writeAccessor; - } - - public ExecutableElementAccessor getPresenceChecker() { - return presenceChecker; - } - - public Type getType() { - return type; - } - - public String getFullName() { - return Strings.join( Arrays.asList( fullName ), "." ); - } - - public PropertyEntry pop() { - if ( fullName.length > 1 ) { - String[] newFullName = Arrays.copyOfRange( fullName, 1, fullName.length ); - return new PropertyEntry(newFullName, readAccessor, writeAccessor, presenceChecker, type ); - } - else { - return null; - } - } - - @Override - public int hashCode() { - int hash = 7; - hash = 23 * hash + Arrays.deepHashCode( this.fullName ); - return hash; - } - - @Override - public boolean equals(Object obj) { - if ( this == obj ) { - return true; - } - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - final PropertyEntry other = (PropertyEntry) obj; - if ( !Arrays.deepEquals( this.fullName, other.fullName ) ) { - return false; - } - return true; - } - - @Override - public String toString() { - return type + " " + Strings.join( Arrays.asList( fullName ), "." ); - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SelectionParameters.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SelectionParameters.java index de95e77b3b..35cdcd9cc0 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SelectionParameters.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SelectionParameters.java @@ -1,29 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; import java.util.Collections; import java.util.List; +import java.util.Objects; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; import org.mapstruct.ap.internal.model.common.SourceRHS; +import org.mapstruct.ap.internal.util.TypeUtils; /** * Holding parameters common to the selection process, common to IterableMapping, BeanMapping, PropertyMapping and @@ -33,21 +21,76 @@ */ public class SelectionParameters { + private static final SelectionParameters EMPTY = new SelectionParameters( + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + null, + null, + null + ); + private final List qualifiers; private final List qualifyingNames; + private final List conditionQualifiers; + private final List conditionQualifyingNames; private final TypeMirror resultType; - private final Types typeUtils; + private final TypeUtils typeUtils; private final SourceRHS sourceRHS; + /** + * Returns new selection parameters + * + * ResultType is not inherited. + * + * @param selectionParameters the selection parameters that need to be copied + * + * @return the selection parameters based on the given ones + */ + public static SelectionParameters forInheritance(SelectionParameters selectionParameters) { + return withoutResultType( selectionParameters ); + } + + public static SelectionParameters withoutResultType(SelectionParameters selectionParameters) { + return new SelectionParameters( + selectionParameters.qualifiers, + selectionParameters.qualifyingNames, + selectionParameters.conditionQualifiers, + selectionParameters.conditionQualifyingNames, + null, + selectionParameters.typeUtils + ); + } + public SelectionParameters(List qualifiers, List qualifyingNames, TypeMirror resultType, - Types typeUtils) { - this( qualifiers, qualifyingNames, resultType, typeUtils, null ); + TypeUtils typeUtils) { + this( + qualifiers, + qualifyingNames, + Collections.emptyList(), + Collections.emptyList(), + resultType, + typeUtils, + null + ); } - private SelectionParameters(List qualifiers, List qualifyingNames, TypeMirror resultType, - Types typeUtils, SourceRHS sourceRHS) { + public SelectionParameters(List qualifiers, List qualifyingNames, + List conditionQualifiers, List conditionQualifyingNames, + TypeMirror resultType, + TypeUtils typeUtils) { + this( qualifiers, qualifyingNames, conditionQualifiers, conditionQualifyingNames, resultType, typeUtils, null ); + } + + private SelectionParameters(List qualifiers, List qualifyingNames, + List conditionQualifiers, List conditionQualifyingNames, + TypeMirror resultType, + TypeUtils typeUtils, SourceRHS sourceRHS) { this.qualifiers = qualifiers; this.qualifyingNames = qualifyingNames; + this.conditionQualifiers = conditionQualifiers; + this.conditionQualifyingNames = conditionQualifyingNames; this.resultType = resultType; this.typeUtils = typeUtils; this.sourceRHS = sourceRHS; @@ -69,6 +112,21 @@ public List getQualifyingNames() { return qualifyingNames; } + /** + * @return qualifiers used for further select the appropriate presence check method based on class and name + */ + public List getConditionQualifiers() { + return conditionQualifiers; + } + + /** + * @return qualifyingNames, used in combination with with @Named + * @see #getConditionQualifiers() + */ + public List getConditionQualifyingNames() { + return conditionQualifyingNames; + } + /** * * @return resultType used for further select the appropriate mapping method based on resultType (bean mapping) @@ -110,24 +168,23 @@ public boolean equals(Object obj) { return false; } - if ( !equals( this.qualifyingNames, other.qualifyingNames ) ) { + if ( !Objects.equals( this.qualifyingNames, other.qualifyingNames ) ) { return false; } - if ( !equals( this.sourceRHS, other.sourceRHS ) ) { + if ( !Objects.equals( this.conditionQualifiers, other.conditionQualifiers ) ) { return false; } - return equals( this.resultType, other.resultType ); - } - - private boolean equals(Object object1, Object object2) { - if ( object1 == null ) { - return (object2 == null); + if ( !Objects.equals( this.conditionQualifyingNames, other.conditionQualifyingNames ) ) { + return false; } - else { - return object1.equals( object2 ); + + if ( !Objects.equals( this.sourceRHS, other.sourceRHS ) ) { + return false; } + + return equals( this.resultType, other.resultType ); } private boolean equals(List mirrors1, List mirrors2) { @@ -155,13 +212,32 @@ private boolean equals(TypeMirror mirror1, TypeMirror mirror2) { } } + public SelectionParameters withSourceRHS(SourceRHS sourceRHS) { + return new SelectionParameters( + this.qualifiers, + this.qualifyingNames, + this.conditionQualifiers, + this.conditionQualifyingNames, + null, + this.typeUtils, + sourceRHS + ); + } + public static SelectionParameters forSourceRHS(SourceRHS sourceRHS) { return new SelectionParameters( - Collections.emptyList(), - Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), null, null, sourceRHS ); } + + public static SelectionParameters empty() { + return EMPTY; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java index a83029db2b..8427dd3eca 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceMethod.java @@ -1,59 +1,44 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Set; - +import java.util.stream.Collectors; +import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.gem.ObjectFactoryGem; import org.mapstruct.ap.internal.model.common.Accessibility; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.prism.ObjectFactoryPrism; -import org.mapstruct.ap.internal.util.AccessorNamingUtils; import org.mapstruct.ap.internal.util.Executables; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.MapperConfiguration; import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.TypeUtils; + +import static org.mapstruct.ap.internal.model.source.MappingMethodUtils.isEnumMapping; +import static org.mapstruct.ap.internal.util.Collections.first; /** * Represents a mapping method with source and target type and the mappings between the properties of source and target * type. *

    * A method can either be configured by itself or by another method for the inverse mapping direction (the appropriate - * setter on {@link MappingOptions} will be called in this case). + * setter on {@link MappingMethodOptions} will be called in this case). * * @author Gunnar Morling */ public class SourceMethod implements Method { - private final Types typeUtils; + private final TypeUtils typeUtils; private final TypeFactory typeFactory; private final Type declaringMapper; @@ -61,31 +46,35 @@ public class SourceMethod implements Method { private final List parameters; private final Parameter mappingTargetParameter; private final Parameter targetTypeParameter; + private final Parameter sourcePropertyNameParameter; + private final Parameter targetPropertyNameParameter; private final boolean isObjectFactory; private final Type returnType; private final Accessibility accessibility; private final List exceptionTypes; - private final MapperConfiguration config; - private final MappingOptions mappingOptions; + private final MappingMethodOptions mappingMethodOptions; + private final ConditionMethodOptions conditionMethodOptions; private final List prototypeMethods; private final Type mapperToImplement; private final List sourceParameters; private final List contextParameters; private final ParameterProvidedMethods contextProvidedMethods; + private final List typeParameters; private List parameterNames; private List applicablePrototypeMethods; private List applicableReversePrototypeMethods; - private Boolean isEnumMapping; private Boolean isValueMapping; private Boolean isIterableMapping; private Boolean isMapMapping; private Boolean isStreamMapping; private final boolean hasObjectFactoryAnnotation; + private final boolean verboseLogging; + public static class Builder { private Type declaringMapper = null; @@ -94,18 +83,23 @@ public static class Builder { private List parameters; private Type returnType = null; private List exceptionTypes; - private Map> mappings; - private IterableMapping iterableMapping = null; - private MapMapping mapMapping = null; - private BeanMapping beanMapping = null; - private Types typeUtils; + private Set mappings; + private IterableMappingOptions iterableMapping = null; + private MapMappingOptions mapMapping = null; + private BeanMappingOptions beanMapping = null; + private TypeUtils typeUtils; private TypeFactory typeFactory = null; - private AccessorNamingUtils accessorNaming = null; - private FormattingMessager messager = null; - private MapperConfiguration mapperConfig = null; + private MapperOptions mapper = null; private List prototypeMethods = Collections.emptyList(); - private List valueMappings; + private List valueMappings; + private EnumMappingOptions enumMappingOptions; private ParameterProvidedMethods contextProvidedMethods; + private Set conditionOptions; + private List typeParameters; + private Set subclassMappings; + + private boolean verboseLogging; + private SubclassValidator subclassValidator; public Builder setDeclaringMapper(Type declaringMapper) { this.declaringMapper = declaringMapper; @@ -132,53 +126,58 @@ public Builder setExceptionTypes(List exceptionTypes) { return this; } - public Builder setMappings(Map> mappings) { + public Builder setMappingOptions(Set mappings) { this.mappings = mappings; return this; } - public Builder setIterableMapping(IterableMapping iterableMapping) { + public Builder setIterableMappingOptions(IterableMappingOptions iterableMapping) { this.iterableMapping = iterableMapping; return this; } - public Builder setMapMapping(MapMapping mapMapping) { + public Builder setMapMappingOptions(MapMappingOptions mapMapping) { this.mapMapping = mapMapping; return this; } - public Builder setBeanMapping(BeanMapping beanMapping) { + public Builder setBeanMappingOptions(BeanMappingOptions beanMapping) { this.beanMapping = beanMapping; return this; } - public Builder setValueMappings(List valueMappings) { + public Builder setValueMappingOptionss(List valueMappings) { this.valueMappings = valueMappings; return this; } - public Builder setTypeUtils(Types typeUtils) { - this.typeUtils = typeUtils; + public Builder setEnumMappingOptions(EnumMappingOptions enumMappingOptions) { + this.enumMappingOptions = enumMappingOptions; return this; } - public Builder setTypeFactory(TypeFactory typeFactory) { - this.typeFactory = typeFactory; + public Builder setSubclassMappings(Set subclassMappings) { + this.subclassMappings = subclassMappings; return this; } - public Builder setAccessorNaming(AccessorNamingUtils accessorNaming) { - this.accessorNaming = accessorNaming; + public Builder setSubclassValidator(SubclassValidator subclassValidator) { + this.subclassValidator = subclassValidator; return this; } - public Builder setMessager(FormattingMessager messager) { - this.messager = messager; + public Builder setTypeUtils(TypeUtils typeUtils) { + this.typeUtils = typeUtils; return this; } - public Builder setMapperConfiguration(MapperConfiguration mapperConfig) { - this.mapperConfig = mapperConfig; + public Builder setTypeFactory(TypeFactory typeFactory) { + this.typeFactory = typeFactory; + return this; + } + + public Builder setMapper(MapperOptions mapper) { + this.mapper = mapper; return this; } @@ -187,7 +186,7 @@ public Builder setPrototypeMethods(List prototypeMethods) { return this; } - public Builder setDefininingType(Type definingType) { + public Builder setDefiningType(Type definingType) { this.definingType = definingType; return this; } @@ -197,25 +196,54 @@ public Builder setContextProvidedMethods(ParameterProvidedMethods contextProvide return this; } - public SourceMethod build() { + public Builder setConditionOptions(Set conditionOptions) { + this.conditionOptions = conditionOptions; + return this; + } - MappingOptions mappingOptions = - new MappingOptions( mappings, iterableMapping, mapMapping, beanMapping, valueMappings, false ); + public Builder setVerboseLogging(boolean verboseLogging) { + this.verboseLogging = verboseLogging; + return this; + } - SourceMethod sourceMethod = new SourceMethod( this, mappingOptions ); + public SourceMethod build() { - if ( mappings != null ) { - for ( Map.Entry> entry : mappings.entrySet() ) { - for ( Mapping mapping : entry.getValue() ) { - mapping.init( sourceMethod, messager, typeFactory, accessorNaming ); - } - } + if ( mappings == null ) { + mappings = Collections.emptySet(); } - return sourceMethod; + + if ( subclassMappings == null ) { + subclassMappings = Collections.emptySet(); + } + + MappingMethodOptions mappingMethodOptions = new MappingMethodOptions( + mapper, + mappings, + iterableMapping, + mapMapping, + beanMapping, + enumMappingOptions, + valueMappings, + subclassMappings, + subclassValidator + ); + + ConditionMethodOptions conditionMethodOptions = + conditionOptions != null ? new ConditionMethodOptions( conditionOptions ) : + ConditionMethodOptions.empty(); + + this.typeParameters = this.executable.getTypeParameters() + .stream() + .map( Element::asType ) + .map( typeFactory::getType ) + .collect( Collectors.toList() ); + + return new SourceMethod( this, mappingMethodOptions, conditionMethodOptions ); } } - private SourceMethod(Builder builder, MappingOptions mappingOptions) { + private SourceMethod(Builder builder, MappingMethodOptions mappingMethodOptions, + ConditionMethodOptions conditionMethodOptions) { this.declaringMapper = builder.declaringMapper; this.executable = builder.executable; this.parameters = builder.parameters; @@ -223,29 +251,36 @@ private SourceMethod(Builder builder, MappingOptions mappingOptions) { this.exceptionTypes = builder.exceptionTypes; this.accessibility = Accessibility.fromModifiers( builder.executable.getModifiers() ); - this.mappingOptions = mappingOptions; + this.mappingMethodOptions = mappingMethodOptions; + this.conditionMethodOptions = conditionMethodOptions; this.sourceParameters = Parameter.getSourceParameters( parameters ); this.contextParameters = Parameter.getContextParameters( parameters ); this.contextProvidedMethods = builder.contextProvidedMethods; + this.typeParameters = builder.typeParameters; this.mappingTargetParameter = Parameter.getMappingTargetParameter( parameters ); this.targetTypeParameter = Parameter.getTargetTypeParameter( parameters ); - this.hasObjectFactoryAnnotation = ObjectFactoryPrism.getInstanceOn( executable ) != null; + this.sourcePropertyNameParameter = Parameter.getSourcePropertyNameParameter( parameters ); + this.targetPropertyNameParameter = Parameter.getTargetPropertyNameParameter( parameters ); + this.hasObjectFactoryAnnotation = ObjectFactoryGem.instanceOn( executable ) != null; this.isObjectFactory = determineIfIsObjectFactory(); this.typeUtils = builder.typeUtils; this.typeFactory = builder.typeFactory; - this.config = builder.mapperConfig; this.prototypeMethods = builder.prototypeMethods; this.mapperToImplement = builder.definingType; + + this.verboseLogging = builder.verboseLogging; } private boolean determineIfIsObjectFactory() { boolean hasNoSourceParameters = getSourceParameters().isEmpty(); boolean hasNoMappingTargetParam = getMappingTargetParameter() == null; + boolean hasNoSourcePropertyNameParam = getSourcePropertyNameParameter() == null; + boolean hasNoTargetPropertyNameParam = getTargetPropertyNameParameter() == null; return !isLifecycleCallbackMethod() && !returnType.isVoid() - && hasNoMappingTargetParam + && hasNoMappingTargetParam && hasNoSourcePropertyNameParam && hasNoTargetPropertyNameParam && ( hasObjectFactoryAnnotation || hasNoSourceParameters ); } @@ -287,7 +322,7 @@ public ParameterProvidedMethods getContextProvidedMethods() { @Override public List getParameterNames() { if ( parameterNames == null ) { - List names = new ArrayList( parameters.size() ); + List names = new ArrayList<>( parameters.size() ); for ( Parameter parameter : parameters ) { names.add( parameter.getName() ); @@ -314,31 +349,20 @@ public Accessibility getAccessibility() { return accessibility; } - public Mapping getSingleMappingByTargetPropertyName(String targetPropertyName) { - List all = mappingOptions.getMappings().get( targetPropertyName ); - return all != null ? first( all ) : null; - } - - public boolean reverses(SourceMethod method) { + public boolean inverses(SourceMethod method) { return method.getDeclaringMapper() == null && method.isAbstract() && getSourceParameters().size() == 1 && method.getSourceParameters().size() == 1 - && first( getSourceParameters() ).getType().isAssignableTo( method.getResultType() ) + && getMappingSourceType().isAssignableTo( method.getResultType() ) && getResultType().isAssignableTo( first( method.getSourceParameters() ).getType() ); } - public boolean isSame(SourceMethod method) { - return getSourceParameters().size() == 1 && method.getSourceParameters().size() == 1 - && equals( first( getSourceParameters() ).getType(), first( method.getSourceParameters() ).getType() ) - && equals( getResultType(), method.getResultType() ); - } - public boolean canInheritFrom(SourceMethod method) { return method.getDeclaringMapper() == null && method.isAbstract() && isMapMapping() == method.isMapMapping() && isIterableMapping() == method.isIterableMapping() - && isEnumMapping() == method.isEnumMapping() + && isEnumMapping( this ) == isEnumMapping( method ) && getResultType().isAssignableTo( method.getResultType() ) && allParametersAreAssignable( getSourceParameters(), method.getSourceParameters() ); } @@ -358,10 +382,18 @@ public Parameter getTargetTypeParameter() { return targetTypeParameter; } + public Parameter getSourcePropertyNameParameter() { + return sourcePropertyNameParameter; + } + + public Parameter getTargetPropertyNameParameter() { + return targetPropertyNameParameter; + } + public boolean isIterableMapping() { if ( isIterableMapping == null ) { isIterableMapping = getSourceParameters().size() == 1 - && first( getSourceParameters() ).getType().isIterableType() + && getMappingSourceType().isIterableType() && getResultType().isIterableType(); } return isIterableMapping; @@ -370,9 +402,9 @@ && first( getSourceParameters() ).getType().isIterableType() public boolean isStreamMapping() { if ( isStreamMapping == null ) { isStreamMapping = getSourceParameters().size() == 1 - && ( first( getSourceParameters() ).getType().isIterableType() && getResultType().isStreamType() - || first( getSourceParameters() ).getType().isStreamType() && getResultType().isIterableType() - || first( getSourceParameters() ).getType().isStreamType() && getResultType().isStreamType() ); + && ( getMappingSourceType().isIterableType() && getResultType().isStreamType() + || getMappingSourceType().isStreamType() && getResultType().isIterableType() + || getMappingSourceType().isStreamType() && getResultType().isStreamType() ); } return isStreamMapping; } @@ -380,17 +412,20 @@ public boolean isStreamMapping() { public boolean isMapMapping() { if ( isMapMapping == null ) { isMapMapping = getSourceParameters().size() == 1 - && first( getSourceParameters() ).getType().isMapType() + && getMappingSourceType().isMapType() && getResultType().isMapType(); } return isMapMapping; } - public boolean isEnumMapping() { - if ( isEnumMapping == null ) { - isEnumMapping = MappingMethodUtils.isEnumMapping( this ); - } - return isEnumMapping; + /** + * Enum Mapping was realized with @Mapping in stead of @ValueMapping. @Mapping is no longer + * supported. + * + * @return true when @Mapping is used in stead of @ValueMapping + */ + public boolean isRemovedEnumMapping() { + return MappingMethodUtils.isEnumMapping( this ); } /** @@ -402,15 +437,11 @@ public boolean isEnumMapping() { public boolean isValueMapping() { if ( isValueMapping == null ) { - isValueMapping = isEnumMapping() && mappingOptions.getMappings().isEmpty(); + isValueMapping = isEnumMapping( this ) && mappingMethodOptions.getMappings().isEmpty(); } return isValueMapping; } - private boolean equals(Object o1, Object o2) { - return (o1 == null && o2 == null) || (o1 != null) && o1.equals( o2 ); - } - @Override public String toString() { StringBuilder sb = new StringBuilder( returnType.toString() ); @@ -425,51 +456,9 @@ public String toString() { return sb.toString(); } - /** - * Returns the {@link Mapping}s for the given source property. - * - * @param sourcePropertyName the source property name - * @return list of mappings - */ - public List getMappingBySourcePropertyName(String sourcePropertyName) { - List mappingsOfSourceProperty = new ArrayList(); - - for ( List mappingOfProperty : mappingOptions.getMappings().values() ) { - for ( Mapping mapping : mappingOfProperty ) { - - if ( isEnumMapping() ) { - if ( mapping.getSourceName().equals( sourcePropertyName ) ) { - mappingsOfSourceProperty.add( mapping ); - } - } - else { - List sourceEntries = mapping.getSourceReference().getPropertyEntries(); - - // there can only be a mapping if there's only one entry for a source property, so: param.property. - // There can be no mapping if there are more entries. So: param.property.property2 - if ( sourceEntries.size() == 1 && sourcePropertyName.equals( first( sourceEntries ).getName() ) ) { - mappingsOfSourceProperty.add( mapping ); - } - } - } - } - - return mappingsOfSourceProperty; - } - - public Parameter getSourceParameter(String sourceParameterName) { - for ( Parameter parameter : getSourceParameters() ) { - if ( parameter.getName().equals( sourceParameterName ) ) { - return parameter; - } - } - - return null; - } - public List getApplicablePrototypeMethods() { if ( applicablePrototypeMethods == null ) { - applicablePrototypeMethods = new ArrayList(); + applicablePrototypeMethods = new ArrayList<>(); for ( SourceMethod prototype : prototypeMethods ) { if ( canInheritFrom( prototype ) ) { @@ -483,10 +472,10 @@ public List getApplicablePrototypeMethods() { public List getApplicableReversePrototypeMethods() { if ( applicableReversePrototypeMethods == null ) { - applicableReversePrototypeMethods = new ArrayList(); + applicableReversePrototypeMethods = new ArrayList<>(); for ( SourceMethod prototype : prototypeMethods ) { - if ( reverses( prototype ) ) { + if ( inverses( prototype ) ) { applicableReversePrototypeMethods.add( prototype ); } } @@ -497,7 +486,7 @@ public List getApplicableReversePrototypeMethods() { private static boolean allParametersAreAssignable(List fromParams, List toParams) { if ( fromParams.size() == toParams.size() ) { - Set unaccountedToParams = new HashSet( toParams ); + Set unaccountedToParams = new HashSet<>( toParams ); for ( Parameter fromParam : fromParams ) { // each fromParam needs at least one match, and all toParam need to be accounted for at the end @@ -542,13 +531,7 @@ public boolean matches(List sourceTypes, Type targetType) { * @return {@code true} if the parameter list contains a parameter annotated with {@code @TargetType} */ public static boolean containsTargetTypeParameter(List parameters) { - for ( Parameter param : parameters ) { - if ( param.isTargetType() ) { - return true; - } - } - - return false; + return parameters.stream().anyMatch( Parameter::isTargetType ); } @Override @@ -557,8 +540,13 @@ public List getThrownTypes() { } @Override - public MappingOptions getMappingOptions() { - return mappingOptions; + public MappingMethodOptions getOptions() { + return mappingMethodOptions; + } + + @Override + public ConditionMethodOptions getConditionOptions() { + return conditionMethodOptions; } @Override @@ -576,11 +564,6 @@ public Type getDefiningType() { return mapperToImplement; } - @Override - public MapperConfiguration getMapperConfiguration() { - return config; - } - @Override public boolean isLifecycleCallbackMethod() { return Executables.isLifecycleCallbackMethod( getExecutable() ); @@ -610,4 +593,23 @@ public boolean isUpdateMethod() { public boolean hasObjectFactoryAnnotation() { return hasObjectFactoryAnnotation; } + + @Override + public List getTypeParameters() { + return this.typeParameters; + } + + @Override + public String describe() { + if ( verboseLogging ) { + return toString(); + } + else { + String mapper = declaringMapper != null ? declaringMapper.getName() + "." : ""; + String sourceTypes = getParameters().stream() + .map( Parameter::describe ) + .collect( Collectors.joining( ", " ) ); + return getResultType().describe() + " " + mapper + getName() + "(" + sourceTypes + ")"; + } + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java deleted file mode 100644 index cfad298162..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SourceReference.java +++ /dev/null @@ -1,402 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import static org.mapstruct.ap.internal.model.source.PropertyEntry.forSourceReference; -import static org.mapstruct.ap.internal.util.Collections.first; -import static org.mapstruct.ap.internal.util.Collections.last; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import javax.lang.model.type.DeclaredType; - -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.util.Extractor; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; -import org.mapstruct.ap.internal.util.Strings; -import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; - -/** - * This class describes the source side of a property mapping. - *

    - * It contains the source parameter, and all individual (nested) property entries. So consider the following - * mapping method: - * - *

    - * @Mapping(source = "in.propA.propB" target = "propC")
    - * TypeB mappingMethod(TypeA in);
    - * 
    - * - * Then: - *
      - *
    • {@code parameter} will describe {@code in}
    • - *
    • {@code propertyEntries[0]} will describe {@code propA}
    • - *
    • {@code propertyEntries[1]} will describe {@code propB}
    • - *
    - * - * After building, {@link #isValid()} will return true when when no problems are detected during building. - * - * @author Sjaak Derksen - */ -public class SourceReference { - - private final Parameter parameter; - private final List propertyEntries; - private final boolean isValid; - - /** - * Builds a {@link SourceReference} from an {@code @Mappping}. - */ - public static class BuilderFromMapping { - - private Mapping mapping; - private SourceMethod method; - private FormattingMessager messager; - private TypeFactory typeFactory; - - public BuilderFromMapping messager(FormattingMessager messager) { - this.messager = messager; - return this; - } - - public BuilderFromMapping mapping(Mapping mapping) { - this.mapping = mapping; - return this; - } - - public BuilderFromMapping method(SourceMethod method) { - this.method = method; - return this; - } - - public BuilderFromMapping typeFactory(TypeFactory typeFactory) { - this.typeFactory = typeFactory; - return this; - } - - public SourceReference build() { - - - String sourceName = mapping.getSourceName(); - - if ( sourceName == null ) { - return null; - } - - boolean isValid = true; - boolean foundEntryMatch; - - String sourceNameTrimmed = sourceName.trim(); - if ( !sourceName.equals( sourceNameTrimmed ) ) { - messager.printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getSourceAnnotationValue(), - Message.PROPERTYMAPPING_WHITESPACE_TRIMMED, - sourceName, - sourceNameTrimmed - ); - } - String[] sourcePropertyNames = new String[0]; - String[] segments = sourceNameTrimmed.split( "\\." ); - Parameter parameter = null; - - List entries = new ArrayList(); - - if ( method.getSourceParameters().size() > 1 ) { - - // parameterName is mandatory for multiple source parameters - if ( segments.length > 0 ) { - String sourceParameterName = segments[0]; - parameter = method.getSourceParameter( sourceParameterName ); - if ( parameter == null ) { - reportMappingError( - Message.PROPERTYMAPPING_INVALID_PARAMETER_NAME, - sourceParameterName, - Strings.join( - method.getSourceParameters(), - ", ", - new Extractor() { - @Override - public String apply(Parameter parameter) { - return parameter.getName(); - } - } - ) - ); - isValid = false; - } - } - if ( segments.length > 1 && parameter != null ) { - sourcePropertyNames = Arrays.copyOfRange( segments, 1, segments.length ); - entries = getSourceEntries( parameter.getType(), sourcePropertyNames ); - foundEntryMatch = ( entries.size() == sourcePropertyNames.length ); - } - else { - // its only a parameter, no property - foundEntryMatch = true; - } - - } - else { - - // parameter name is not mandatory for single source parameter - sourcePropertyNames = segments; - parameter = method.getSourceParameters().get( 0 ); - entries = getSourceEntries( parameter.getType(), sourcePropertyNames ); - foundEntryMatch = ( entries.size() == sourcePropertyNames.length ); - - if ( !foundEntryMatch ) { - //Lets see if the expression contains the parameterName, so parameterName.propName1.propName2 - if ( parameter.getName().equals( segments[0] ) ) { - sourcePropertyNames = Arrays.copyOfRange( segments, 1, segments.length ); - entries = getSourceEntries( parameter.getType(), sourcePropertyNames ); - foundEntryMatch = ( entries.size() == sourcePropertyNames.length ); - } - else { - // segment[0] cannot be attributed to the parameter name. - parameter = null; - } - } - } - - if ( !foundEntryMatch ) { - - if ( parameter != null ) { - reportMappingError( Message.PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER, parameter.getName(), - Strings.join( Arrays.asList( sourcePropertyNames ), "." ) - ); - } - else { - int notFoundPropertyIndex = 0; - Type sourceType = method.getParameters().get( 0 ).getType(); - if ( !entries.isEmpty() ) { - notFoundPropertyIndex = entries.size(); - sourceType = last( entries ).getType(); - } - String mostSimilarWord = Strings.getMostSimilarWord( - sourcePropertyNames[notFoundPropertyIndex], - sourceType.getPropertyReadAccessors().keySet() - ); - List elements = new ArrayList( - Arrays.asList( sourcePropertyNames ).subList( 0, notFoundPropertyIndex ) - ); - elements.add( mostSimilarWord ); - reportMappingError( - Message.PROPERTYMAPPING_INVALID_PROPERTY_NAME, mapping.getSourceName(), - Strings.join( elements, "." ) - ); - } - isValid = false; - } - - return new SourceReference( parameter, entries, isValid ); - } - - private List getSourceEntries(Type type, String[] entryNames) { - List sourceEntries = new ArrayList(); - Type newType = type; - for ( String entryName : entryNames ) { - boolean matchFound = false; - Map sourceReadAccessors = newType.getPropertyReadAccessors(); - Map sourcePresenceCheckers = newType.getPropertyPresenceCheckers(); - - for ( Map.Entry getter : sourceReadAccessors.entrySet() ) { - if ( getter.getKey().equals( entryName ) ) { - newType = typeFactory.getReturnType( - (DeclaredType) newType.getTypeMirror(), - getter.getValue() - ); - sourceEntries.add( forSourceReference( entryName, getter.getValue(), - sourcePresenceCheckers.get( entryName ), newType - ) ); - matchFound = true; - break; - } - } - if ( !matchFound ) { - break; - } - } - return sourceEntries; - } - - private void reportMappingError(Message msg, Object... objects) { - messager.printMessage( method.getExecutable(), mapping.getMirror(), mapping.getSourceAnnotationValue(), - msg, objects - ); - } - } - - /** - * Builds a {@link SourceReference} from a property. - */ - public static class BuilderFromProperty { - - private String name; - private Accessor readAccessor; - private ExecutableElementAccessor presenceChecker; - private Type type; - private Parameter sourceParameter; - - public BuilderFromProperty name(String name) { - this.name = name; - return this; - } - - public BuilderFromProperty readAccessor(Accessor readAccessor) { - this.readAccessor = readAccessor; - return this; - } - - public BuilderFromProperty presenceChecker(ExecutableElementAccessor presenceChecker) { - this.presenceChecker = presenceChecker; - return this; - } - - public BuilderFromProperty type(Type type) { - this.type = type; - return this; - } - - public BuilderFromProperty sourceParameter(Parameter sourceParameter) { - this.sourceParameter = sourceParameter; - return this; - } - - public SourceReference build() { - List sourcePropertyEntries = new ArrayList(); - if ( readAccessor != null ) { - sourcePropertyEntries.add( forSourceReference( name, readAccessor, presenceChecker, type ) ); - } - return new SourceReference( sourceParameter, sourcePropertyEntries, true ); - } - } - - /** - * Builds a {@link SourceReference} from a property. - */ - public static class BuilderFromSourceReference { - - private Parameter sourceParameter; - private SourceReference sourceReference; - - public BuilderFromSourceReference sourceReference(SourceReference sourceReference) { - this.sourceReference = sourceReference; - return this; - } - - public BuilderFromSourceReference sourceParameter(Parameter sourceParameter) { - this.sourceParameter = sourceParameter; - return this; - } - - public SourceReference build() { - return new SourceReference( sourceParameter, sourceReference.propertyEntries, true ); - } - } - - private SourceReference(Parameter sourceParameter, List sourcePropertyEntries, boolean isValid) { - this.parameter = sourceParameter; - this.propertyEntries = sourcePropertyEntries; - this.isValid = isValid; - } - - public Parameter getParameter() { - return parameter; - } - - public List getPropertyEntries() { - return propertyEntries; - } - - public boolean isValid() { - return isValid; - } - - public List getElementNames() { - List sourceName = new ArrayList(); - sourceName.add( parameter.getName() ); - for ( PropertyEntry propertyEntry : propertyEntries ) { - sourceName.add( propertyEntry.getName() ); - } - return sourceName; - } - - /** - * Creates a copy of this reference, which is adapted to the given method - * - * @param method the method to create the copy for - * @return the copy - */ - public SourceReference copyForInheritanceTo(SourceMethod method) { - List replacementParamCandidates = new ArrayList(); - for ( Parameter sourceParam : method.getSourceParameters() ) { - if ( parameter != null && sourceParam.getType().isAssignableTo( parameter.getType() ) ) { - replacementParamCandidates.add( sourceParam ); - } - } - - Parameter replacement = parameter; - if ( replacementParamCandidates.size() == 1 ) { - replacement = first( replacementParamCandidates ); - } - - return new SourceReference( replacement, propertyEntries, isValid ); - } - - public SourceReference pop() { - if ( propertyEntries.size() > 1 ) { - List newPropertyEntries = - new ArrayList( propertyEntries.subList( 1, propertyEntries.size() ) ); - return new SourceReference( parameter, newPropertyEntries, isValid ); - } - else { - return null; - } - } - - @Override - public String toString() { - - if ( propertyEntries.isEmpty() ) { - return String.format( "parameter \"%s %s\"", getParameter().getType(), getParameter().getName() ); - } - else if ( propertyEntries.size() == 1 ) { - PropertyEntry propertyEntry = propertyEntries.get( 0 ); - return String.format( "property \"%s %s\"", propertyEntry.getType(), propertyEntry.getName() ); - } - else { - PropertyEntry lastPropertyEntry = propertyEntries.get( propertyEntries.size() - 1 ); - return String.format( - "property \"%s %s\"", - lastPropertyEntry.getType(), - Strings.join( getElementNames(), "." ) - ); - } - } - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java new file mode 100644 index 0000000000..2b0e6dd13e --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassMappingOptions.java @@ -0,0 +1,235 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.gem.SubclassMappingGem; +import org.mapstruct.ap.internal.gem.SubclassMappingsGem; +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.ap.spi.TypeHierarchyErroneousException; + +import static org.mapstruct.ap.internal.util.Message.SUBCLASSMAPPING_ILLEGAL_SUBCLASS; +import static org.mapstruct.ap.internal.util.Message.SUBCLASSMAPPING_NO_VALID_SUPERCLASS; +import static org.mapstruct.ap.internal.util.Message.SUBCLASSMAPPING_UPDATE_METHODS_NOT_SUPPORTED; + +/** + * Represents a subclass mapping as configured via {@code @SubclassMapping}. + * + * @author Ben Zegveld + */ +public class SubclassMappingOptions extends DelegatingOptions { + + private final TypeMirror source; + private final TypeMirror target; + private final TypeUtils typeUtils; + private final SelectionParameters selectionParameters; + private final SubclassMappingGem subclassMapping; + + public SubclassMappingOptions(TypeMirror source, TypeMirror target, TypeUtils typeUtils, DelegatingOptions next, + SelectionParameters selectionParameters, SubclassMappingGem subclassMapping) { + super( next ); + this.source = source; + this.target = target; + this.typeUtils = typeUtils; + this.selectionParameters = selectionParameters; + this.subclassMapping = subclassMapping; + } + + @Override + public boolean hasAnnotation() { + return source != null && target != null; + } + + private static boolean isConsistent(SubclassMappingGem gem, ExecutableElement method, FormattingMessager messager, + TypeUtils typeUtils, List sourceParameters, Type resultType, + SubclassValidator subclassValidator) { + + if ( resultType == null ) { + messager.printMessage( method, gem.mirror(), SUBCLASSMAPPING_UPDATE_METHODS_NOT_SUPPORTED ); + return false; + } + + TypeMirror sourceSubclass = gem.source().getValue(); + TypeMirror targetSubclass = gem.target().getValue(); + TypeMirror targetParentType = resultType.getTypeMirror(); + validateTypeMirrors( sourceSubclass, targetSubclass, targetParentType ); + + boolean isConsistent = true; + + boolean isChildOfAParameter = false; + for ( Parameter sourceParameter : sourceParameters ) { + TypeMirror sourceParentType = sourceParameter.getType().getTypeMirror(); + validateTypeMirrors( sourceParentType ); + isChildOfAParameter = isChildOfAParameter || isChildOfParent( typeUtils, sourceSubclass, sourceParentType ); + } + if ( !isChildOfAParameter ) { + messager + .printMessage( + method, + gem.mirror(), + SUBCLASSMAPPING_NO_VALID_SUPERCLASS, + sourceSubclass.toString() ); + isConsistent = false; + } + if ( !isChildOfParent( typeUtils, targetSubclass, targetParentType ) ) { + messager + .printMessage( + method, + gem.mirror(), + SUBCLASSMAPPING_ILLEGAL_SUBCLASS, + targetParentType.toString(), + targetSubclass.toString() ); + isConsistent = false; + } + if ( !subclassValidator.isValidUsage( method, gem.mirror(), sourceSubclass ) ) { + isConsistent = false; + } + return isConsistent; + } + + private static void validateTypeMirrors(TypeMirror... typeMirrors) { + for ( TypeMirror typeMirror : typeMirrors ) { + if ( typeMirror == null ) { + // When a class used in uses or imports is created by another annotation processor + // then javac will not return correct TypeMirror with TypeKind#ERROR, but rather a string "" + // the gem tools would return a null TypeMirror in that case. + // Therefore throw TypeHierarchyErroneousException so we can postpone the generation of the mapper + throw new TypeHierarchyErroneousException( typeMirror ); + } + } + } + + private static boolean isChildOfParent(TypeUtils typeUtils, TypeMirror childType, TypeMirror parentType) { + return typeUtils.isSubtype( childType, parentType ); + } + + public TypeMirror getSource() { + return source; + } + + public TypeMirror getTarget() { + return target; + } + + public SelectionParameters getSelectionParameters() { + return selectionParameters; + } + + public AnnotationMirror getMirror() { + return Optional.ofNullable( subclassMapping ).map( SubclassMappingGem::mirror ).orElse( null ); + } + + public static void addInstances(SubclassMappingsGem gem, ExecutableElement method, + BeanMappingOptions beanMappingOptions, FormattingMessager messager, + TypeUtils typeUtils, Set mappings, + List sourceParameters, Type resultType, + SubclassValidator subclassValidator) { + for ( SubclassMappingGem subclassMapping : gem.value().get() ) { + addInstance( + subclassMapping, + method, + beanMappingOptions, + messager, + typeUtils, + mappings, + sourceParameters, + resultType, + subclassValidator ); + } + } + + public static void addInstance(SubclassMappingGem subclassMapping, ExecutableElement method, + BeanMappingOptions beanMappingOptions, FormattingMessager messager, + TypeUtils typeUtils, Set mappings, + List sourceParameters, Type resultType, + SubclassValidator subclassValidator) { + if ( !isConsistent( + subclassMapping, + method, + messager, + typeUtils, + sourceParameters, + resultType, + subclassValidator ) ) { + return; + } + + TypeMirror sourceSubclass = subclassMapping.source().getValue(); + TypeMirror targetSubclass = subclassMapping.target().getValue(); + SelectionParameters selectionParameters = new SelectionParameters( + subclassMapping.qualifiedBy().get(), + subclassMapping.qualifiedByName().get(), + targetSubclass, + typeUtils + ); + + mappings + .add( + new SubclassMappingOptions( + sourceSubclass, + targetSubclass, + typeUtils, + beanMappingOptions, + selectionParameters, + subclassMapping + ) ); + } + + public static List copyForInverseInheritance(Set mappings, + BeanMappingOptions beanMappingOptions) { + // we are not interested in keeping it unique at this point. + return mappings.stream().map( mapping -> new SubclassMappingOptions( + mapping.target, + mapping.source, + mapping.typeUtils, + beanMappingOptions, + mapping.selectionParameters, + mapping.subclassMapping + ) ).collect( Collectors.toCollection( ArrayList::new ) ); + } + + public static List copyForInheritance(Set subclassMappings, + BeanMappingOptions beanMappingOptions) { + // we are not interested in keeping it unique at this point. + List mappings = new ArrayList<>(); + for ( SubclassMappingOptions subclassMapping : subclassMappings ) { + mappings.add( + new SubclassMappingOptions( + subclassMapping.source, + subclassMapping.target, + subclassMapping.typeUtils, + beanMappingOptions, + subclassMapping.selectionParameters, + subclassMapping.subclassMapping ) ); + } + return mappings; + } + + @Override + public boolean equals(Object obj) { + if ( obj == null || !( obj instanceof SubclassMappingOptions ) ) { + return false; + } + SubclassMappingOptions other = (SubclassMappingOptions) obj; + return typeUtils.isSameType( source, other.source ); + } + + @Override + public int hashCode() { + return 1; // use a stable value because TypeMirror is not safe to use for hashCode. + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassValidator.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassValidator.java new file mode 100644 index 0000000000..601b588e42 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/SubclassValidator.java @@ -0,0 +1,62 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.ArrayList; +import java.util.List; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.TypeUtils; + +/** + * Handles the validation of multiple @SubclassMapping annotations on the same method. + * + * @author Ben Zegveld + */ +public class SubclassValidator { + + private final FormattingMessager messager; + private final List handledSubclasses = new ArrayList<>(); + private final TypeUtils typeUtils; + + public SubclassValidator(FormattingMessager messager, TypeUtils typeUtils) { + this.messager = messager; + this.typeUtils = typeUtils; + } + + public boolean isValidUsage(Element e, AnnotationMirror annotation, TypeMirror sourceType) { + for ( TypeMirror typeMirror : handledSubclasses ) { + if ( typeUtils.isSameType( sourceType, typeMirror ) ) { + messager + .printMessage( + e, + annotation, + Message.SUBCLASSMAPPING_DOUBLE_SOURCE_SUBCLASS, + sourceType ); + return false; + } + if ( typeUtils.isAssignable( sourceType, typeMirror ) ) { + messager + .printMessage( + e, + annotation, + Message.SUBCLASSMAPPING_ILLOGICAL_ORDER, + sourceType, + typeMirror, + sourceType, + typeMirror ); + return false; + } + } + handledSubclasses.add( sourceType ); + return true; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java deleted file mode 100644 index 327b7a290c..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/TargetReference.java +++ /dev/null @@ -1,456 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; - -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.type.DeclaredType; - -import org.mapstruct.ap.internal.model.common.Parameter; -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; -import org.mapstruct.ap.internal.util.AccessorNamingUtils; -import org.mapstruct.ap.internal.util.Executables; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; -import org.mapstruct.ap.internal.util.Strings; -import org.mapstruct.ap.internal.util.accessor.Accessor; - -/** - * This class describes the target side of a property mapping. - *

    - * It contains the target parameter, and all individual (nested) property entries. So consider the following mapping - * method: - * - *

    - * @Mapping(source = "in.propA.propB" target = "propC")
    - * TypeB mappingMethod(TypeA in);
    - * 
    - * - * Then: - *
      - *
    • {@code parameter} will describe {@code in}
    • - *
    • {@code propertyEntries[0]} will describe {@code propA}
    • - *
    • {@code propertyEntries[1]} will describe {@code propB}
    • - *
    - * - * After building, {@link #isValid()} will return true when when no problems are detected during building. - * - * @author Sjaak Derksen - */ -public class TargetReference { - - private final Parameter parameter; - private final List propertyEntries; - private final boolean isValid; - - - /** - * Builds a {@link TargetReference} from an {@code @Mappping}. - */ - public static class BuilderFromTargetMapping { - - private Mapping mapping; - private SourceMethod method; - private FormattingMessager messager; - private TypeFactory typeFactory; - private AccessorNamingUtils accessorNaming; - private boolean isReverse; - /** - * Needed when we are building from reverse mapping. It is needed, so we can remove the first level if it is - * needed. - * E.g. If we have a mapping like: - * - * {@literal @}Mapping( target = "letterSignature", source = "dto.signature" ) - * - * - * When it is reversed it will look like: - * - * {@literal @}Mapping( target = "dto.signature", source = "letterSignature" ) - * - * - * The {@code dto} needs to be considered as a possibility for a target name only if a Target Reference for - * a reverse is created. - */ - private Parameter reverseSourceParameter; - /** - * During {@link #getTargetEntries(Type, String[])} an error can occur. However, we are invoking - * that multiple times because the first entry can also be the name of the parameter. Therefore we keep - * the error message until the end when we can report it. - */ - private MappingErrorMessage errorMessage; - - public BuilderFromTargetMapping messager(FormattingMessager messager) { - this.messager = messager; - return this; - } - - public BuilderFromTargetMapping mapping(Mapping mapping) { - this.mapping = mapping; - return this; - } - - public BuilderFromTargetMapping method(SourceMethod method) { - this.method = method; - return this; - } - - public BuilderFromTargetMapping typeFactory(TypeFactory typeFactory) { - this.typeFactory = typeFactory; - return this; - } - - public BuilderFromTargetMapping accessorNaming(AccessorNamingUtils accessorNaming) { - this.accessorNaming = accessorNaming; - return this; - } - - public BuilderFromTargetMapping isReverse(boolean isReverse) { - this.isReverse = isReverse; - return this; - } - - public BuilderFromTargetMapping reverseSourceParameter(Parameter reverseSourceParameter) { - this.reverseSourceParameter = reverseSourceParameter; - return this; - } - - public TargetReference build() { - - String targetName = mapping.getTargetName(); - - if ( targetName == null ) { - return null; - } - - String targetNameTrimmed = targetName.trim(); - if ( !targetName.equals( targetNameTrimmed ) ) { - messager.printMessage( - method.getExecutable(), - mapping.getMirror(), - mapping.getTargetAnnotationValue(), - Message.PROPERTYMAPPING_WHITESPACE_TRIMMED, - targetName, - targetNameTrimmed - ); - } - String[] segments = targetNameTrimmed.split( "\\." ); - Parameter parameter = method.getMappingTargetParameter(); - - boolean foundEntryMatch; - Type resultType = method.getResultType(); - resultType = typeBasedOnMethod( resultType ); - - // there can be 4 situations - // 1. Return type - // 2. A reverse target reference where the source parameter name is used in the original mapping - // 3. @MappingTarget, with - // 4. or without parameter name. - String[] targetPropertyNames = segments; - List entries = getTargetEntries( resultType, targetPropertyNames ); - foundEntryMatch = (entries.size() == targetPropertyNames.length); - if ( !foundEntryMatch && segments.length > 1 - && matchesSourceOrTargetParameter( segments[0], parameter, reverseSourceParameter, isReverse ) ) { - targetPropertyNames = Arrays.copyOfRange( segments, 1, segments.length ); - entries = getTargetEntries( resultType, targetPropertyNames ); - foundEntryMatch = (entries.size() == targetPropertyNames.length); - } - - if ( !foundEntryMatch && errorMessage != null && !isReverse ) { - // This is called only for reporting errors - errorMessage.report( ); - } - - // foundEntryMatch = isValid, errors are handled here, and the BeanMapping uses that to ignore - // the creation of mapping for invalid TargetReferences - return new TargetReference( parameter, entries, foundEntryMatch ); - } - - private List getTargetEntries(Type type, String[] entryNames) { - - // initialize - CollectionMappingStrategyPrism cms = method.getMapperConfiguration().getCollectionMappingStrategy(); - List targetEntries = new ArrayList(); - Type nextType = type; - - // iterate, establish for each entry the target write accessors. Other than setter is only allowed for - // last entry - for ( int i = 0; i < entryNames.length; i++ ) { - - Type mappingType = typeBasedOnMethod( nextType ); - Accessor targetReadAccessor = mappingType.getPropertyReadAccessors().get( entryNames[i] ); - Accessor targetWriteAccessor = mappingType.getPropertyWriteAccessors( cms ).get( entryNames[i] ); - boolean isLast = i == entryNames.length - 1; - boolean isNotLast = i < entryNames.length - 1; - if ( isWriteAccessorNotValidWhenNotLast( targetWriteAccessor, isNotLast ) - || isWriteAccessorNotValidWhenLast( targetWriteAccessor, targetReadAccessor, mapping, isLast ) ) { - // there should always be a write accessor (except for the last when the mapping is ignored and - // there is a read accessor) and there should be read accessor mandatory for all but the last - setErrorMessage( targetWriteAccessor, targetReadAccessor, entryNames, i, nextType ); - break; - } - - if ( isLast || ( accessorNaming.isSetterMethod( targetWriteAccessor ) - || Executables.isFieldAccessor( targetWriteAccessor ) ) ) { - // only intermediate nested properties when they are a true setter or field accessor - // the last may be other readAccessor (setter / getter / adder). - - nextType = findNextType( nextType, targetWriteAccessor, targetReadAccessor ); - - // check if an entry alread exists, otherwise create - String[] fullName = Arrays.copyOfRange( entryNames, 0, i + 1 ); - PropertyEntry propertyEntry = PropertyEntry.forTargetReference( fullName, targetReadAccessor, - targetWriteAccessor, nextType ); - targetEntries.add( propertyEntry ); - } - - } - - return targetEntries; - } - - /** - * Finds the next type based on the initial type. - * - * @param initial for which a next type should be found - * @param targetWriteAccessor the write accessor - * @param targetReadAccessor the read accessor - * @return the next type that should be used for finding a property entry - */ - private Type findNextType(Type initial, Accessor targetWriteAccessor, Accessor targetReadAccessor) { - Type nextType; - Accessor toUse = targetWriteAccessor != null ? targetWriteAccessor : targetReadAccessor; - if ( accessorNaming.isGetterMethod( toUse ) || - Executables.isFieldAccessor( toUse ) ) { - nextType = typeFactory.getReturnType( - (DeclaredType) typeBasedOnMethod( initial ).getTypeMirror(), - toUse - ); - } - else { - nextType = typeFactory.getSingleParameter( - (DeclaredType) typeBasedOnMethod( initial ).getTypeMirror(), - toUse - ).getType(); - } - return nextType; - } - - private void setErrorMessage(Accessor targetWriteAccessor, Accessor targetReadAccessor, String[] entryNames, - int index, Type nextType) { - if ( targetWriteAccessor == null && targetReadAccessor == null ) { - errorMessage = new NoPropertyErrorMessage( mapping, method, messager, entryNames, index, nextType ); - } - else if ( targetWriteAccessor == null ) { - errorMessage = new NoWriteAccessorErrorMessage( mapping, method, messager ); - } - else { - //TODO there is no read accessor. What should we do here? - errorMessage = new NoPropertyErrorMessage( mapping, method, messager, entryNames, index, nextType ); - } - } - - /** - * When we are in an update method, i.e. source parameter with {@code @MappingTarget} then the type should - * be itself, otherwise, we always get the effective type. The reason is that when doing updates we always - * search for setters and getters within the updating type. - */ - private Type typeBasedOnMethod(Type type) { - if ( method.isUpdateMethod() ) { - return type; - } - else { - return type.getEffectiveType(); - } - } - - /** - * A write accessor is not valid if it is {@code null} and it is not last. i.e. for nested target mappings - * there must be a write accessor for all entries except the last one. - * - * @param accessor that needs to be checked - * @param isNotLast whether or not this is the last write accessor in the entry chain - * - * @return {@code true} if the accessor is not valid, {@code false} otherwise - */ - private static boolean isWriteAccessorNotValidWhenNotLast(Accessor accessor, boolean isNotLast) { - return accessor == null && isNotLast; - } - - /** - * For a last accessor to be valid, a read accessor should exist and the mapping should be ignored. All other - * cases represent an invalid write accessor. This method will evaluate to {@code true} if the following is - * {@code true}: - *
      - *
    • {@code writeAccessor} is {@code null}
    • - *
    • It is for the last entry
    • - *
    • A read accessor does not exist, or the mapping is not ignored
    • - *
    - * - * @param writeAccessor that needs to be checked - * @param readAccessor that is used - * @param mapping that is used - * @param isLast whether or not this is the last write accessor in the entry chain - * - * @return {@code true} if the write accessor is not valid, {@code false} otherwise. See description for more - * information - */ - private static boolean isWriteAccessorNotValidWhenLast(Accessor writeAccessor, Accessor readAccessor, - Mapping mapping, boolean isLast) { - return writeAccessor == null && isLast && ( readAccessor == null || !mapping.isIgnored() ); - } - - /** - * Validates that the {@code segment} is the same as the {@code targetParameter} or the {@code - * reverseSourceParameter} names - * - * @param segment that needs to be checked - * @param targetParameter the target parameter if it exists - * @param reverseSourceParameter the reverse source parameter if it exists - * @param isReverse whether a reverse {@link TargetReference} is being built - * - * @return {@code true} if the segment matches the name of the {@code targetParameter} or the name of the - * {@code reverseSourceParameter} when this is a reverse {@link TargetReference} is being built, {@code - * false} otherwise - */ - private static boolean matchesSourceOrTargetParameter(String segment, Parameter targetParameter, - Parameter reverseSourceParameter, boolean isReverse) { - boolean matchesTargetParameter = - targetParameter != null && targetParameter.getName().equals( segment ); - return matchesTargetParameter - || isReverse && reverseSourceParameter != null && reverseSourceParameter.getName().equals( segment ); - } - } - - private TargetReference(Parameter sourceParameter, List sourcePropertyEntries, boolean isValid) { - this.parameter = sourceParameter; - this.propertyEntries = sourcePropertyEntries; - this.isValid = isValid; - } - - public Parameter getParameter() { - return parameter; - } - - public List getPropertyEntries() { - return propertyEntries; - } - - public boolean isValid() { - return isValid; - } - - public List getElementNames() { - List elementNames = new ArrayList(); - if ( parameter != null ) { - // only relevant for source properties - elementNames.add( parameter.getName() ); - } - for ( PropertyEntry propertyEntry : propertyEntries ) { - elementNames.add( propertyEntry.getName() ); - } - return elementNames; - } - - public TargetReference pop() { - if ( propertyEntries.size() > 1 ) { - List newPropertyEntries = new ArrayList( propertyEntries.size() - 1 ); - for ( PropertyEntry propertyEntry : propertyEntries ) { - PropertyEntry newPropertyEntry = propertyEntry.pop(); - if ( newPropertyEntry != null ) { - newPropertyEntries.add( newPropertyEntry ); - } - } - return new TargetReference( null, newPropertyEntries, isValid ); - } - else { - return null; - } - } - - private abstract static class MappingErrorMessage { - private final Mapping mapping; - private final SourceMethod method; - private final FormattingMessager messager; - - private MappingErrorMessage(Mapping mapping, SourceMethod method, FormattingMessager messager) { - this.mapping = mapping; - this.method = method; - this.messager = messager; - } - - abstract void report(); - - protected void printErrorMessage(Message message, Object... args) { - Object[] errorArgs = new Object[args.length + 2]; - errorArgs[0] = mapping.getTargetName(); - errorArgs[1] = method.getResultType(); - System.arraycopy( args, 0, errorArgs, 2, args.length ); - AnnotationMirror annotationMirror = mapping.getMirror(); - messager.printMessage( method.getExecutable(), annotationMirror, mapping.getSourceAnnotationValue(), - message, errorArgs - ); - } - } - - private static class NoWriteAccessorErrorMessage extends MappingErrorMessage { - - private NoWriteAccessorErrorMessage(Mapping mapping, SourceMethod method, FormattingMessager messager) { - super( mapping, method, messager ); - } - - @Override - public void report() { - printErrorMessage( Message.BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE ); - } - } - - private static class NoPropertyErrorMessage extends MappingErrorMessage { - - private final String[] entryNames; - private final int index; - private final Type nextType; - - private NoPropertyErrorMessage(Mapping mapping, SourceMethod method, FormattingMessager messager, - String[] entryNames, int index, Type nextType) { - super( mapping, method, messager ); - this.entryNames = entryNames; - this.index = index; - this.nextType = nextType; - } - - @Override - public void report() { - - Set readAccessors = nextType.getPropertyReadAccessors().keySet(); - String mostSimilarProperty = Strings.getMostSimilarWord( entryNames[index], readAccessors ); - - List elements = new ArrayList( Arrays.asList( entryNames ).subList( 0, index ) ); - elements.add( mostSimilarProperty ); - - printErrorMessage( Message.BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE, Strings.join( elements, "." ) ); - } - } - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ValueMapping.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ValueMapping.java deleted file mode 100644 index 31ccbdfb12..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ValueMapping.java +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.source; - -import java.util.List; - -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.AnnotationValue; -import javax.lang.model.element.ExecutableElement; - -import org.mapstruct.ap.internal.prism.MappingConstantsPrism; -import org.mapstruct.ap.internal.prism.ValueMappingPrism; -import org.mapstruct.ap.internal.prism.ValueMappingsPrism; -import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.Message; - -/** - * Represents the mapping between one value constant and another. - * - * @author Sjaak Derksen - */ -public class ValueMapping { - - private final String source; - private final String target; - private final AnnotationMirror mirror; - private final AnnotationValue sourceAnnotationValue; - private final AnnotationValue targetAnnotationValue; - - public static void fromMappingsPrism(ValueMappingsPrism mappingsAnnotation, ExecutableElement method, - FormattingMessager messager, List mappings) { - - boolean anyFound = false; - for ( ValueMappingPrism mappingPrism : mappingsAnnotation.value() ) { - ValueMapping mapping = fromMappingPrism( mappingPrism, method, messager ); - if ( mapping != null ) { - - if ( !mappings.contains( mapping ) ) { - mappings.add( mapping ); - } - else { - messager.printMessage( - method, - mappingPrism.mirror, - mappingPrism.values.target(), - Message.VALUEMAPPING_DUPLICATE_SOURCE, - mappingPrism.source() - ); - } - if ( MappingConstantsPrism.ANY_REMAINING.equals( mapping.source ) - || MappingConstantsPrism.ANY_UNMAPPED.equals( mapping.source ) ) { - if ( anyFound ) { - messager.printMessage( - method, - mappingPrism.mirror, - mappingPrism.values.target(), - Message.VALUEMAPPING_ANY_AREADY_DEFINED, - mappingPrism.source() - ); - } - anyFound = true; - } - } - } - } - - public static ValueMapping fromMappingPrism(ValueMappingPrism mappingPrism, ExecutableElement element, - FormattingMessager messager) { - - return new ValueMapping( mappingPrism.source(), mappingPrism.target(), mappingPrism.mirror, - mappingPrism.values.source(), mappingPrism.values.target() ); - } - - private ValueMapping(String source, String target, AnnotationMirror mirror, AnnotationValue sourceAnnotationValue, - AnnotationValue targetAnnotationValue ) { - this.source = source; - this.target = target; - this.mirror = mirror; - this.sourceAnnotationValue = sourceAnnotationValue; - this.targetAnnotationValue = targetAnnotationValue; - } - - /** - * @return the name of the constant in the source. - */ - public String getSource() { - return source; - } - - /** - * @return the name of the constant in the target. - */ - public String getTarget() { - return target; - } - - public AnnotationMirror getMirror() { - return mirror; - } - - public AnnotationValue getSourceAnnotationValue() { - return sourceAnnotationValue; - } - - public AnnotationValue getTargetAnnotationValue() { - return targetAnnotationValue; - } - - public ValueMapping reverse() { - ValueMapping result; - if ( !MappingConstantsPrism.ANY_REMAINING.equals( source ) - || !MappingConstantsPrism.ANY_UNMAPPED.equals( source ) ) { - result = new ValueMapping( - target, - source, - mirror, - sourceAnnotationValue, - targetAnnotationValue ); - } - else { - result = null; - } - return result; - } - - @Override - public int hashCode() { - int hash = 5; - hash = 97 * hash + (this.source != null ? this.source.hashCode() : 0); - return hash; - } - - @Override - public boolean equals(Object obj) { - if ( obj == null ) { - return false; - } - if ( getClass() != obj.getClass() ) { - return false; - } - final ValueMapping other = (ValueMapping) obj; - if ( (this.source == null) ? (other.source != null) : !this.source.equals( other.source ) ) { - return false; - } - return true; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/ValueMappingOptions.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ValueMappingOptions.java new file mode 100644 index 0000000000..9c412733c4 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/ValueMappingOptions.java @@ -0,0 +1,148 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source; + +import java.util.Objects; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.ExecutableElement; + +import org.mapstruct.ap.internal.gem.ValueMappingGem; +import org.mapstruct.ap.internal.gem.ValueMappingsGem; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; + +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_REMAINING; +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.ANY_UNMAPPED; +import static org.mapstruct.ap.internal.gem.MappingConstantsGem.THROW_EXCEPTION; + +/** + * Represents the mapping between one value constant and another. + * + * @author Sjaak Derksen + */ +public class ValueMappingOptions { + + private final String source; + private final String target; + private final AnnotationMirror mirror; + private final AnnotationValue sourceAnnotationValue; + private final AnnotationValue targetAnnotationValue; + + public static void fromMappingsGem(ValueMappingsGem mappingsGem, ExecutableElement method, + FormattingMessager messager, Set mappings) { + + boolean anyFound = false; + for ( ValueMappingGem mappingGem : mappingsGem.value().get() ) { + ValueMappingOptions mapping = fromMappingGem( mappingGem ); + if ( mapping != null ) { + + if ( !mappings.contains( mapping ) ) { + mappings.add( mapping ); + } + else { + messager.printMessage( + method, + mappingGem.mirror(), + mappingGem.target().getAnnotationValue(), + Message.VALUEMAPPING_DUPLICATE_SOURCE, + mappingGem.source().get() + ); + } + if ( ANY_REMAINING.equals( mapping.source ) + || ANY_UNMAPPED.equals( mapping.source ) ) { + if ( anyFound ) { + messager.printMessage( + method, + mappingGem.mirror(), + mappingGem.target().getAnnotationValue(), + Message.VALUEMAPPING_ANY_AREADY_DEFINED, + mappingGem.source().get() + ); + } + anyFound = true; + } + } + } + } + + public static ValueMappingOptions fromMappingGem(ValueMappingGem mapping ) { + + return new ValueMappingOptions( mapping.source().get(), mapping.target().get(), mapping.mirror(), + mapping.source().getAnnotationValue(), mapping.target().getAnnotationValue() ); + } + + private ValueMappingOptions(String source, String target, AnnotationMirror mirror, + AnnotationValue sourceAnnotationValue, AnnotationValue targetAnnotationValue ) { + this.source = source; + this.target = target; + this.mirror = mirror; + this.sourceAnnotationValue = sourceAnnotationValue; + this.targetAnnotationValue = targetAnnotationValue; + } + + /** + * @return the name of the constant in the source. + */ + public String getSource() { + return source; + } + + /** + * @return the name of the constant in the target. + */ + public String getTarget() { + return target; + } + + public AnnotationMirror getMirror() { + return mirror; + } + + public AnnotationValue getSourceAnnotationValue() { + return sourceAnnotationValue; + } + + public AnnotationValue getTargetAnnotationValue() { + return targetAnnotationValue; + } + + public ValueMappingOptions inverse() { + ValueMappingOptions result; + if ( !(ANY_REMAINING.equals( source ) || ANY_UNMAPPED.equals( source ) || THROW_EXCEPTION.equals( target ) ) ) { + result = new ValueMappingOptions( + target, + source, + mirror, + sourceAnnotationValue, + targetAnnotationValue ); + } + else { + result = null; + } + return result; + } + + @Override + public int hashCode() { + int hash = 5; + hash = 97 * hash + (this.source != null ? this.source.hashCode() : 0); + return hash; + } + + @Override + public boolean equals(Object obj) { + if ( obj == null ) { + return false; + } + if ( getClass() != obj.getClass() ) { + return false; + } + final ValueMappingOptions other = (ValueMappingOptions) obj; + return Objects.equals( this.source, other.source ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/AbstractToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/AbstractToXmlGregorianCalendar.java new file mode 100644 index 0000000000..87a4648d49 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/AbstractToXmlGregorianCalendar.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.builtin; + +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.ConstructorFragment; +import org.mapstruct.ap.internal.model.common.FieldReference; +import org.mapstruct.ap.internal.model.common.FinalField; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; + +/** + * Base class for built-in methods for converting from a particular type to {@code XMLGregorianCalendar}. + * + * @author Sjaak Derksen + */ +public abstract class AbstractToXmlGregorianCalendar extends BuiltInMethod { + + private final Type returnType; + private final Set importTypes; + private final Type dataTypeFactoryType; + + public AbstractToXmlGregorianCalendar(TypeFactory typeFactory) { + this.returnType = typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ); + this.dataTypeFactoryType = typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_FACTORY ); + this.importTypes = asSet( + returnType, + dataTypeFactoryType, + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONFIGURATION_EXCEPTION ) + ); + } + + @Override + public Set getImportTypes() { + return importTypes; + } + + @Override + public Type getReturnType() { + return returnType; + } + + @Override + public FieldReference getFieldReference() { + return new FinalField( dataTypeFactoryType, "datatypeFactory" ); + } + + @Override + public ConstructorFragment getConstructorFragment() { + return new NewDatatypeFactoryConstructorFragment( ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java index 58bd170034..6cd1605b23 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMappingMethods.java @@ -1,28 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; import java.util.ArrayList; import java.util.List; +import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.util.JavaTimeConstants; import org.mapstruct.ap.internal.util.JaxbConstants; import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.internal.util.XmlConstants; @@ -38,7 +25,7 @@ public class BuiltInMappingMethods { public BuiltInMappingMethods(TypeFactory typeFactory) { boolean isXmlGregorianCalendarPresent = isXmlGregorianCalendarAvailable( typeFactory ); - builtInMethods = new ArrayList( 20 ); + builtInMethods = new ArrayList<>( 21 ); if ( isXmlGregorianCalendarPresent ) { builtInMethods.add( new DateToXmlGregorianCalendar( typeFactory ) ); builtInMethods.add( new XmlGregorianCalendarToDate( typeFactory ) ); @@ -46,23 +33,26 @@ public BuiltInMappingMethods(TypeFactory typeFactory) { builtInMethods.add( new XmlGregorianCalendarToString( typeFactory ) ); builtInMethods.add( new CalendarToXmlGregorianCalendar( typeFactory ) ); builtInMethods.add( new XmlGregorianCalendarToCalendar( typeFactory ) ); + builtInMethods.add( new ZonedDateTimeToXmlGregorianCalendar( typeFactory ) ); + builtInMethods.add( new XmlGregorianCalendarToLocalDate( typeFactory ) ); + builtInMethods.add( new LocalDateToXmlGregorianCalendar( typeFactory ) ); + builtInMethods.add( new LocalDateTimeToXmlGregorianCalendar( typeFactory ) ); + builtInMethods.add( new XmlGregorianCalendarToLocalDateTime( typeFactory ) ); } - if ( isJaxbAvailable( typeFactory ) ) { - builtInMethods.add( new JaxbElemToValue( typeFactory ) ); + if ( isJavaxJaxbAvailable( typeFactory ) ) { + Type type = typeFactory.getType( JaxbConstants.JAVAX_JAXB_ELEMENT_FQN ); + builtInMethods.add( new JaxbElemToValue( type ) ); } - - if ( isJava8TimeAvailable( typeFactory ) ) { - builtInMethods.add( new ZonedDateTimeToCalendar( typeFactory ) ); - builtInMethods.add( new ZonedDateTimeToXmlGregorianCalendar( typeFactory ) ); - builtInMethods.add( new CalendarToZonedDateTime( typeFactory ) ); - if ( isXmlGregorianCalendarPresent ) { - builtInMethods.add( new XmlGregorianCalendarToLocalDate( typeFactory ) ); - builtInMethods.add( new LocalDateToXmlGregorianCalendar( typeFactory ) ); - } + if ( isJakartaJaxbAvailable( typeFactory ) ) { + Type type = typeFactory.getType( JaxbConstants.JAKARTA_JAXB_ELEMENT_FQN ); + builtInMethods.add( new JaxbElemToValue( type ) ); } + builtInMethods.add( new ZonedDateTimeToCalendar( typeFactory ) ); + builtInMethods.add( new CalendarToZonedDateTime( typeFactory ) ); + if ( isJodaTimeAvailable( typeFactory ) && isXmlGregorianCalendarPresent ) { builtInMethods.add( new JodaDateTimeToXmlGregorianCalendar( typeFactory ) ); builtInMethods.add( new XmlGregorianCalendarToJodaDateTime( typeFactory ) ); @@ -75,17 +65,16 @@ public BuiltInMappingMethods(TypeFactory typeFactory) { } } - private static boolean isJaxbAvailable(TypeFactory typeFactory) { - return JaxbConstants.isJaxbElementPresent() && typeFactory.isTypeAvailable( JaxbConstants.JAXB_ELEMENT_FQN ); + private static boolean isJavaxJaxbAvailable(TypeFactory typeFactory) { + return typeFactory.isTypeAvailable( JaxbConstants.JAVAX_JAXB_ELEMENT_FQN ); } - private static boolean isJava8TimeAvailable(TypeFactory typeFactory) { - return typeFactory.isTypeAvailable( JavaTimeConstants.ZONED_DATE_TIME_FQN ); + private static boolean isJakartaJaxbAvailable(TypeFactory typeFactory) { + return typeFactory.isTypeAvailable( JaxbConstants.JAKARTA_JAXB_ELEMENT_FQN ); } private static boolean isXmlGregorianCalendarAvailable(TypeFactory typeFactory) { - return XmlConstants.isXmlGregorianCalendarPresent() && - typeFactory.isTypeAvailable( XmlConstants.JAVAX_XML_DATATYPE_XMLGREGORIAN_CALENDAR ); + return typeFactory.isTypeAvailable( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ); } private static boolean isJodaTimeAvailable(TypeFactory typeFactory) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java index 60c939c691..de034d2011 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/BuiltInMethod.java @@ -1,47 +1,33 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Set; - import javax.lang.model.element.ExecutableElement; -import org.mapstruct.ap.internal.conversion.SimpleConversion; import org.mapstruct.ap.internal.model.common.Accessibility; +import org.mapstruct.ap.internal.model.common.ConstructorFragment; import org.mapstruct.ap.internal.model.common.ConversionContext; +import org.mapstruct.ap.internal.model.common.FieldReference; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.source.MappingOptions; +import org.mapstruct.ap.internal.model.source.MappingMethodOptions; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; -import org.mapstruct.ap.internal.util.MapperConfiguration; import org.mapstruct.ap.internal.util.Strings; +import static org.mapstruct.ap.internal.util.Collections.first; + /** * Represents a "built-in" mapping method which will be added as private method to the generated mapper. Built-in - * methods are used in cases where a {@link SimpleConversion} doesn't suffice, e.g. as several lines of source code or a + * methods are used in cases where a simple conversation doesn't suffice, e.g. as several lines of source code or a * try/catch block are required. * * @author Sjaak Derksen @@ -66,7 +52,7 @@ public String getName() { * @return the types used by this method for which import statements need to be generated */ public Set getImportTypes() { - return Collections.emptySet(); + return Collections.emptySet(); } /** @@ -83,21 +69,13 @@ public boolean matches(List sourceTypes, Type targetType) { Type sourceType = first( sourceTypes ); - if ( getReturnType().isAssignableTo( targetType.erasure() ) - && sourceType.erasure().isAssignableTo( getParameter().getType() ) ) { - return doTypeVarsMatch( sourceType, targetType ); - } - if ( getReturnType().getFullyQualifiedName().equals( "java.lang.Object" ) - && sourceType.erasure().isAssignableTo( getParameter().getType() ) ) { - // return type could be a type parameter T - return doTypeVarsMatch( sourceType, targetType ); - } - if ( getReturnType().isAssignableTo( targetType.erasure() ) - && getParameter().getType().getFullyQualifiedName().equals( "java.lang.Object" ) ) { - // parameter type could be a type parameter T - return doTypeVarsMatch( sourceType, targetType ); + Type returnType = getReturnType().resolveParameterToType( sourceType, getParameter().getType() ).getMatch(); + if ( returnType == null ) { + return false; } - return false; + + return returnType.isAssignableTo( targetType ) + && sourceType.erasure().isAssignableTo( getParameter().getType() ); } @Override @@ -175,6 +153,11 @@ public String getContextParameter(ConversionContext conversionContext) { return null; } + @Override + public List getTypeParameters() { + return Collections.emptyList(); + } + /** * hashCode based on class * @@ -206,7 +189,7 @@ public boolean equals(Object obj) { * * @param parameter source * @param returnType target - * @return {@code true}, iff the the type variables match + * @return {@code true}, iff the type variables match */ public boolean doTypeVarsMatch(Type parameter, Type returnType) { return true; @@ -236,7 +219,7 @@ public Type getResultType() { @Override public List getParameterNames() { - List parameterNames = new ArrayList( getParameters().size() ); + List parameterNames = new ArrayList<>( getParameters().size() ); for ( Parameter parameter : getParameters() ) { parameterNames.add( parameter.getName() ); } @@ -269,11 +252,6 @@ public Type getDefiningType() { return null; } - @Override - public MapperConfiguration getMapperConfiguration() { - return null; - } - @Override public boolean isLifecycleCallbackMethod() { return false; @@ -285,7 +263,22 @@ public boolean isUpdateMethod() { } @Override - public MappingOptions getMappingOptions() { - return MappingOptions.empty(); + public MappingMethodOptions getOptions() { + return MappingMethodOptions.empty(); + } + + public FieldReference getFieldReference() { + return null; + } + + public ConstructorFragment getConstructorFragment() { + return null; + } + + @Override + public String describe() { + // the name of the builtin method is never fully qualified, so no need to distinguish + // between verbose or not. The type knows whether it should log verbose + return getResultType().describe() + ":" + getName() + "(" + getMappingSourceType().describe() + ")"; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.java index 6aed447a07..3461538c41 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.java @@ -1,62 +1,44 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Calendar; import java.util.GregorianCalendar; import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import static org.mapstruct.ap.internal.util.Collections.asSet; + /** + * A built-in method for converting from {@link Calendar} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class CalendarToXmlGregorianCalendar extends BuiltInMethod { +public class CalendarToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public CalendarToXmlGregorianCalendar(TypeFactory typeFactory) { + super( typeFactory ); this.parameter = new Parameter( "cal ", typeFactory.getType( Calendar.class ) ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); - this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( GregorianCalendar.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( GregorianCalendar.class ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( this.importTypes ); + return result; } @Override @@ -64,8 +46,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.java index 08614f3fea..729b65e5e9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Set; @@ -27,7 +12,8 @@ import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.util.JavaTimeConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * {@link BuiltInMethod} for mapping between {@link Calendar} and {@link ZonedDateTime}. @@ -41,7 +27,7 @@ public class CalendarToZonedDateTime extends BuiltInMethod { private final Set importedTypes; CalendarToZonedDateTime(TypeFactory typeFactory) { - this.returnType = typeFactory.getType( JavaTimeConstants.ZONED_DATE_TIME_FQN ); + this.returnType = typeFactory.getType( ZonedDateTime.class ); this.parameter = new Parameter( "cal", typeFactory.getType( Calendar.class ) ); this.importedTypes = asSet( returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.java index 9979fcf65f..fb556e68a1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.java @@ -1,62 +1,44 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Date; import java.util.GregorianCalendar; import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import static org.mapstruct.ap.internal.util.Collections.asSet; + /** + * A built-in method for converting from {@link Date} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class DateToXmlGregorianCalendar extends BuiltInMethod { +public class DateToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public DateToXmlGregorianCalendar(TypeFactory typeFactory) { + super( typeFactory ); this.parameter = new Parameter( "date", typeFactory.getType( Date.class ) ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); - this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( GregorianCalendar.class ), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( GregorianCalendar.class ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( this.importTypes ); + return result; } @Override @@ -64,8 +46,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java index 49a386b8dc..2a5d1639e6 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.java @@ -1,45 +1,29 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.bind.JAXBElement; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.common.TypeFactory; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * @author Sjaak Derksen */ -public class JaxbElemToValue extends BuiltInMethod { +class JaxbElemToValue extends BuiltInMethod { private final Parameter parameter; private final Type returnType; private final Set importTypes; - public JaxbElemToValue(TypeFactory typeFactory) { - this.parameter = new Parameter( "element", typeFactory.getType( JAXBElement.class ) ); - this.returnType = typeFactory.getType( Object.class ); + JaxbElemToValue(Type type) { + this.parameter = new Parameter( "element", type ); + this.returnType = type.getTypeParameters().get( 0 ); this.importTypes = asSet( parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.java index 3e707d13c5..ef57e03175 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.java @@ -1,63 +1,36 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; /** + * A built-in method for converting from Joda {@code DateTime} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class JodaDateTimeToXmlGregorianCalendar extends BuiltInMethod { +public class JodaDateTimeToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; - private final Set importTypes; public JodaDateTimeToXmlGregorianCalendar(TypeFactory typeFactory) { - this.parameter = new Parameter( - "dt", - typeFactory.getType( JodaTimeConstants.DATE_TIME_FQN ) - ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); - - this.importTypes = asSet( - returnType, - parameter.getType(), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ) - ); + super( typeFactory ); + this.parameter = new Parameter("dt", typeFactory.getType( JodaTimeConstants.DATE_TIME_FQN ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.add( parameter.getType() ); + return result; } @Override @@ -65,8 +38,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.java index 79d008b0bf..285ebb29fe 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.java @@ -1,65 +1,44 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from Joda {@code LocalDateTime} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class JodaLocalDateTimeToXmlGregorianCalendar extends BuiltInMethod { +public class JodaLocalDateTimeToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public JodaLocalDateTimeToXmlGregorianCalendar(TypeFactory typeFactory) { - this.parameter = new Parameter( - "dt", - typeFactory.getType( JodaTimeConstants.LOCAL_DATE_TIME_FQN ) - ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); - + super( typeFactory ); + this.parameter = new Parameter( "dt", typeFactory.getType( JodaTimeConstants.LOCAL_DATE_TIME_FQN ) ); this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( DatatypeConstants.class ), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; } @Override @@ -67,8 +46,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.java index b66bea8dc6..8163aa2fb2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.java @@ -1,65 +1,44 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from Joda {@code LocalDate} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class JodaLocalDateToXmlGregorianCalendar extends BuiltInMethod { +public class JodaLocalDateToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public JodaLocalDateToXmlGregorianCalendar(TypeFactory typeFactory) { - this.parameter = new Parameter( - "dt", - typeFactory.getType( JodaTimeConstants.LOCAL_DATE_FQN ) - ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); - + super( typeFactory ); + this.parameter = new Parameter( "dt", typeFactory.getType( JodaTimeConstants.LOCAL_DATE_FQN ) ); this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( DatatypeConstants.class ), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; } @Override @@ -67,8 +46,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.java index 2b4188864c..4fca4e0ed3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.java @@ -1,65 +1,44 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from Joda {@code LocalTime} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class JodaLocalTimeToXmlGregorianCalendar extends BuiltInMethod { +public class JodaLocalTimeToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public JodaLocalTimeToXmlGregorianCalendar(TypeFactory typeFactory) { - this.parameter = new Parameter( - "dt", - typeFactory.getType( JodaTimeConstants.LOCAL_TIME_FQN ) - ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); - + super( typeFactory ); + this.parameter = new Parameter( "dt", typeFactory.getType( JodaTimeConstants.LOCAL_TIME_FQN ) ); this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( DatatypeConstants.class ), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; } @Override @@ -67,8 +46,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateTimeToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateTimeToXmlGregorianCalendar.java new file mode 100644 index 0000000000..b52c7fb586 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateTimeToXmlGregorianCalendar.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.builtin; + +import java.time.LocalDateTime; +import java.time.temporal.ChronoField; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; + +/** + * A built-in method for converting from {@link LocalDateTime} to {@code XMLGregorianCalendar}. + * + * @author Andrei Arlou + */ +public class LocalDateTimeToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { + + private final Parameter parameter; + private final Set importTypes; + + public LocalDateTimeToXmlGregorianCalendar(TypeFactory typeFactory) { + super( typeFactory ); + this.parameter = new Parameter( "localDateTime", typeFactory.getType( LocalDateTime.class ) ); + this.importTypes = asSet( + parameter.getType(), + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ), + typeFactory.getType( ChronoField.class ) + ); + } + + @Override + public Set getImportTypes() { + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; + } + + @Override + public Parameter getParameter() { + return parameter; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.java index 7a5e48820d..e2ec7d7696 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.java @@ -1,70 +1,49 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.time.LocalDate; import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@link LocalDate} to {@code XMLGregorianCalendar}. + * * @author Gunnar Morling */ -public class LocalDateToXmlGregorianCalendar extends BuiltInMethod { +public class LocalDateToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public LocalDateToXmlGregorianCalendar(TypeFactory typeFactory) { + super( typeFactory ); this.parameter = new Parameter( "localDate", typeFactory.getType( LocalDate.class ) ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ), - typeFactory.getType( DatatypeConstants.class ) + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ) ); } @Override - public Parameter getParameter() { - return parameter; + public Set getImportTypes() { + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; } @Override - public Type getReturnType() { - return returnType; + public Parameter getParameter() { + return parameter; } - @Override - public Set getImportTypes() { - return importTypes; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/NewDatatypeFactoryConstructorFragment.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/NewDatatypeFactoryConstructorFragment.java new file mode 100644 index 0000000000..e4f00f7d57 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/NewDatatypeFactoryConstructorFragment.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.builtin; + +import org.mapstruct.ap.internal.model.common.ConstructorFragment; + +public class NewDatatypeFactoryConstructorFragment implements ConstructorFragment { + + public NewDatatypeFactoryConstructorFragment() { + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.java index 1f7f1a0b5e..635853d0fe 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.java @@ -1,66 +1,49 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.GregorianCalendar; import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import static org.mapstruct.ap.internal.util.Collections.asSet; + /** + * A built-in method for converting from {@link String} to {@code XMLGregorianCalendar}. + * * @author Sjaak Derksen */ -public class StringToXmlGregorianCalendar extends BuiltInMethod { +public class StringToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public StringToXmlGregorianCalendar(TypeFactory typeFactory) { + super( typeFactory ); this.parameter = new Parameter( "date", typeFactory.getType( String.class ) ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); this.importTypes = asSet( - returnType, typeFactory.getType( GregorianCalendar.class ), typeFactory.getType( SimpleDateFormat.class ), typeFactory.getType( DateFormat.class ), - typeFactory.getType( ParseException.class ), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( ParseException.class ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; } @Override @@ -68,11 +51,6 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } - @Override public String getContextParameter(ConversionContext conversionContext) { return conversionContext.getDateFormat() != null ? "\"" + conversionContext.getDateFormat() + "\"" : "null"; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.java index 87f0087b1c..e52b306af0 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Calendar; import java.util.Set; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@code XMLGregorianCalendar} to {@link Calendar}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToCalendar extends BuiltInMethod { @@ -39,7 +27,7 @@ public class XmlGregorianCalendarToCalendar extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToCalendar(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( Calendar.class ); this.importTypes = asSet( returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.java index be1cf7c0f3..fd3d9a33a6 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Date; import java.util.Set; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@code XMLGregorianCalendar} to {@link Date}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToDate extends BuiltInMethod { @@ -39,7 +27,7 @@ public class XmlGregorianCalendarToDate extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToDate(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( Date.class ); this.importTypes = asSet( returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.java index 72d80867b1..93ec3e8f96 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.java @@ -1,35 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - +import java.util.Calendar; import java.util.Set; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.XMLGregorianCalendar; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from Joda {@code DateTime} to {@link Calendar}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToJodaDateTime extends BuiltInMethod { @@ -39,10 +28,10 @@ public class XmlGregorianCalendarToJodaDateTime extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToJodaDateTime(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( JodaTimeConstants.DATE_TIME_FQN ); this.importTypes = asSet( - typeFactory.getType( DatatypeConstants.class ), + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ), typeFactory.getType( JodaTimeConstants.DATE_TIME_ZONE_FQN ), returnType, parameter.getType() ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.java index 76ddfa47aa..9a9c1561fc 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.XMLGregorianCalendar; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@code XMLGregorianCalendar} to Joda {@code LocalDate}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToJodaLocalDate extends BuiltInMethod { @@ -39,10 +27,10 @@ public class XmlGregorianCalendarToJodaLocalDate extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToJodaLocalDate(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( JodaTimeConstants.LOCAL_DATE_FQN ); this.importTypes = asSet( - typeFactory.getType( DatatypeConstants.class ), + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ), returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.java index 440da1ea1a..a8d36a13cf 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.XMLGregorianCalendar; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@code XMLGregorianCalendar} to Joda {@code LocalDateTime}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToJodaLocalDateTime extends BuiltInMethod { @@ -39,10 +27,10 @@ public class XmlGregorianCalendarToJodaLocalDateTime extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToJodaLocalDateTime(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( JodaTimeConstants.LOCAL_DATE_TIME_FQN ); this.importTypes = asSet( - typeFactory.getType( DatatypeConstants.class ), + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ), returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.java index 7ee55ea2c3..b26450d560 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Set; -import javax.xml.datatype.DatatypeConstants; -import javax.xml.datatype.XMLGregorianCalendar; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.util.JodaTimeConstants; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * Conversion from {@code XMLGregorianCalendar} to Joda {@code LocalTime}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToJodaLocalTime extends BuiltInMethod { @@ -39,10 +27,10 @@ public class XmlGregorianCalendarToJodaLocalTime extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToJodaLocalTime(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( JodaTimeConstants.LOCAL_TIME_FQN ); this.importTypes = asSet( - typeFactory.getType( DatatypeConstants.class ), + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ), returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.java index 48bd25992f..7bcd5902a5 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.time.LocalDate; import java.util.Set; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@code XMLGregorianCalendar} to {@link LocalDate}. + * * @author Gunnar Morling */ public class XmlGregorianCalendarToLocalDate extends BuiltInMethod { @@ -39,7 +27,7 @@ public class XmlGregorianCalendarToLocalDate extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToLocalDate(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( LocalDate.class ); this.importTypes = asSet( returnType, parameter.getType() ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDateTime.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDateTime.java new file mode 100644 index 0000000000..21b4c57854 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDateTime.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.builtin; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.Set; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; + +/** + * A built-in method for converting from {@code XMLGregorianCalendar} to {@link LocalDateTime}. + * + * @author Andrei Arlou + */ +public class XmlGregorianCalendarToLocalDateTime extends BuiltInMethod { + + private final Parameter parameter; + private final Type returnType; + private final Set importTypes; + + public XmlGregorianCalendarToLocalDateTime(TypeFactory typeFactory) { + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); + this.returnType = typeFactory.getType( LocalDateTime.class ); + this.importTypes = asSet( + returnType, + parameter.getType(), + typeFactory.getType( XmlConstants.JAVAX_XML_DATATYPE_CONSTANTS ), + typeFactory.getType( Duration.class ) + ); + } + + @Override + public Parameter getParameter() { + return parameter; + } + + @Override + public Type getReturnType() { + return returnType; + } + + @Override + public Set getImportTypes() { + return importTypes; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.java index befbed87b9..e293a9c80b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.java @@ -1,37 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.text.SimpleDateFormat; import java.util.Date; import java.util.Set; -import javax.xml.datatype.XMLGregorianCalendar; - import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.util.XmlConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@code XMLGregorianCalendar} to {@link String}. + * * @author Sjaak Derksen */ public class XmlGregorianCalendarToString extends BuiltInMethod { @@ -41,7 +29,7 @@ public class XmlGregorianCalendarToString extends BuiltInMethod { private final Set importTypes; public XmlGregorianCalendarToString(TypeFactory typeFactory) { - this.parameter = new Parameter( "xcal", typeFactory.getType( XMLGregorianCalendar.class ) ); + this.parameter = new Parameter( "xcal", typeFactory.getType( XmlConstants.JAVAX_XML_XML_GREGORIAN_CALENDAR ) ); this.returnType = typeFactory.getType( String.class ); this.importTypes = asSet( parameter.getType(), diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.java index a99cf5c571..5a6c447908 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.time.ZonedDateTime; import java.util.Calendar; import java.util.Set; @@ -28,7 +13,8 @@ import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.util.JavaTimeConstants; + +import static org.mapstruct.ap.internal.util.Collections.asSet; /** * {@link BuiltInMethod} for mapping between {@link Calendar} and {@link ZonedDateTime}. @@ -42,7 +28,7 @@ public class ZonedDateTimeToCalendar extends BuiltInMethod { ZonedDateTimeToCalendar(TypeFactory typeFactory) { this.returnType = typeFactory.getType( Calendar.class ); - this.parameter = new Parameter( "dateTime", typeFactory.getType( JavaTimeConstants.ZONED_DATE_TIME_FQN ) ); + this.parameter = new Parameter( "dateTime", typeFactory.getType( ZonedDateTime.class ) ); this.importedTypes = asSet( returnType, parameter.getType(), typeFactory.getType( TimeZone.class ) ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.java index a06e78da7e..d9e39b388e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.java @@ -1,29 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.builtin; import java.time.ZonedDateTime; import java.util.GregorianCalendar; import java.util.Set; -import javax.xml.datatype.DatatypeConfigurationException; -import javax.xml.datatype.DatatypeFactory; -import javax.xml.datatype.XMLGregorianCalendar; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; @@ -32,30 +16,30 @@ import static org.mapstruct.ap.internal.util.Collections.asSet; /** + * A built-in method for converting from {@link ZonedDateTime} to {@code XMLGregorianCalendar}. + * * @author Christian Bandowski */ -public class ZonedDateTimeToXmlGregorianCalendar extends BuiltInMethod { +public class ZonedDateTimeToXmlGregorianCalendar extends AbstractToXmlGregorianCalendar { private final Parameter parameter; - private final Type returnType; private final Set importTypes; public ZonedDateTimeToXmlGregorianCalendar(TypeFactory typeFactory) { + super( typeFactory ); this.parameter = new Parameter( "zdt ", typeFactory.getType( ZonedDateTime.class ) ); - this.returnType = typeFactory.getType( XMLGregorianCalendar.class ); this.importTypes = asSet( - returnType, parameter.getType(), - typeFactory.getType( DatatypeFactory.class ), - typeFactory.getType( GregorianCalendar.class ), - typeFactory.getType( DatatypeConfigurationException.class ) + typeFactory.getType( GregorianCalendar.class ) ); } @Override public Set getImportTypes() { - return importTypes; + Set result = super.getImportTypes(); + result.addAll( importTypes ); + return result; } @Override @@ -63,8 +47,4 @@ public Parameter getParameter() { return parameter; } - @Override - public Type getReturnType() { - return returnType; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/package-info.java index e74466ff39..040ed91f4a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/builtin/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

    diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/package-info.java index 456649b219..f59fc2f2f3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/package-info.java @@ -1,25 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

    * Intermediary representation of mapping methods as retrieved from via the annotation processing API. The intermediary * representation is then processed into the mapper model representation. + * + * This intermediary presentation is primarily constructed in the + * {@link org.mapstruct.ap.internal.processor.MapperCreationProcessor} and used + * in the {@link org.mapstruct.ap.internal.processor.MapperCreationProcessor} *

    */ package org.mapstruct.ap.internal.model.source; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/CreateOrUpdateSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/CreateOrUpdateSelector.java index 6ac3371de2..b6e5ca0a53 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/CreateOrUpdateSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/CreateOrUpdateSelector.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.ArrayList; import java.util.List; -import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; /** @@ -42,17 +28,17 @@ public class CreateOrUpdateSelector implements MethodSelector { @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, Type targetType, - SelectionCriteria criteria) { - - if ( criteria.isLifecycleCallbackRequired() || criteria.isObjectFactoryRequired() ) { + public List> getMatchingMethods(List> methods, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); + if ( criteria.isLifecycleCallbackRequired() || criteria.isObjectFactoryRequired() + || criteria.isSourceParameterCheckRequired() + || criteria.isPresenceCheckRequired() ) { return methods; } - List> createCandidates = new ArrayList>(); - List> updateCandidates = new ArrayList>(); + List> createCandidates = new ArrayList<>(); + List> updateCandidates = new ArrayList<>(); for ( SelectedMethod method : methods ) { boolean isCreateCandidate = method.getMethod().getMappingTargetParameter() == null; if ( isCreateCandidate ) { @@ -62,10 +48,8 @@ public List> getMatchingMethods(Method mapp updateCandidates.add( method ); } } - if ( criteria.isPreferUpdateMapping() ) { - if ( !updateCandidates.isEmpty() ) { - return updateCandidates; - } + if ( criteria.isPreferUpdateMapping() && !updateCandidates.isEmpty() ) { + return updateCandidates; } return createCandidates; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/FactoryParameterSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/FactoryParameterSelector.java index 8571f51831..50896195f1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/FactoryParameterSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/FactoryParameterSelector.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.ArrayList; import java.util.List; -import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; /** @@ -34,16 +20,14 @@ public class FactoryParameterSelector implements MethodSelector { @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - ListsourceTypes, - Type targetType, - SelectionCriteria criteria) { + public List> getMatchingMethods(List> methods, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); if ( !criteria.isObjectFactoryRequired() || methods.size() <= 1 ) { return methods; } - List> sourceParamFactoryMethods = new ArrayList>( methods.size() ); + List> sourceParamFactoryMethods = new ArrayList<>( methods.size() ); for ( SelectedMethod candidate : methods ) { if ( !candidate.getMethod().getSourceParameters().isEmpty() ) { diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/InheritanceSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/InheritanceSelector.java index b077b20527..7b56564ba9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/InheritanceSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/InheritanceSelector.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; import java.util.List; @@ -27,6 +12,8 @@ import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; +import static org.mapstruct.ap.internal.util.Collections.first; + /** * Selects on inheritance distance, e.g. the amount of inheritance steps from the parameter type. * @@ -35,26 +22,22 @@ public class InheritanceSelector implements MethodSelector { @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, - Type targetType, - SelectionCriteria criteria) { + public List> getMatchingMethods(List> methods, + SelectionContext context) { - if ( sourceTypes.size() != 1 ) { + Type sourceType = context.getSourceType(); + if ( sourceType == null ) { return methods; } - Type singleSourceType = first( sourceTypes ); - - List> candidatesWithBestMatchingSourceType = new ArrayList>(); + List> candidatesWithBestMatchingSourceType = new ArrayList<>(); int bestMatchingSourceTypeDistance = Integer.MAX_VALUE; - // find the methods with the minimum distance regarding getParameter getParameter type + // Find methods with the minimum inheritance distance from the source parameter type for ( SelectedMethod method : methods ) { Parameter singleSourceParam = first( method.getMethod().getSourceParameters() ); - int sourceTypeDistance = singleSourceType.distanceTo( singleSourceParam.getType() ); + int sourceTypeDistance = sourceType.distanceTo( singleSourceParam.getType() ); bestMatchingSourceTypeDistance = addToCandidateListIfMinimal( candidatesWithBestMatchingSourceType, @@ -66,17 +49,17 @@ public List> getMatchingMethods(Method mapp return candidatesWithBestMatchingSourceType; } - private int addToCandidateListIfMinimal(List> candidatesWithBestMathingType, + private int addToCandidateListIfMinimal(List> candidatesWithBestMatchingType, int bestMatchingTypeDistance, SelectedMethod method, int currentTypeDistance) { if ( currentTypeDistance == bestMatchingTypeDistance ) { - candidatesWithBestMathingType.add( method ); + candidatesWithBestMatchingType.add( method ); } else if ( currentTypeDistance < bestMatchingTypeDistance ) { bestMatchingTypeDistance = currentTypeDistance; - candidatesWithBestMathingType.clear(); - candidatesWithBestMathingType.add( method ); + candidatesWithBestMatchingType.clear(); + candidatesWithBestMatchingType.add( method ); } return bestMatchingTypeDistance; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JakartaXmlElementDeclSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JakartaXmlElementDeclSelector.java new file mode 100644 index 0000000000..d5595ef6b7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JakartaXmlElementDeclSelector.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.selector; + +import javax.lang.model.element.Element; + +import org.mapstruct.ap.internal.gem.jakarta.XmlElementDeclGem; +import org.mapstruct.ap.internal.gem.jakarta.XmlElementRefGem; +import org.mapstruct.ap.internal.util.TypeUtils; + +/** + * The concrete implementation of the {@link XmlElementDeclSelector} that + * works with {@link jakarta.xml.bind.annotation.XmlElementRef} and + * {@link jakarta.xml.bind.annotation.XmlElementDecl}. + * + * @author Iaroslav Bogdanchikov + */ +class JakartaXmlElementDeclSelector extends XmlElementDeclSelector { + + JakartaXmlElementDeclSelector(TypeUtils typeUtils) { + super( typeUtils ); + } + + @Override + XmlElementDeclInfo getXmlElementDeclInfo(Element element) { + XmlElementDeclGem gem = XmlElementDeclGem.instanceOn( element ); + + if ( gem == null ) { + return null; + } + + return new XmlElementDeclInfo( gem.name().get(), gem.scope().get() ); + } + + @Override + XmlElementRefInfo getXmlElementRefInfo(Element element) { + XmlElementRefGem gem = XmlElementRefGem.instanceOn( element ); + + if ( gem == null ) { + return null; + } + + return new XmlElementRefInfo( gem.name().get(), gem.type().get() ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JavaxXmlElementDeclSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JavaxXmlElementDeclSelector.java new file mode 100644 index 0000000000..912da3e696 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/JavaxXmlElementDeclSelector.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.selector; + +import javax.lang.model.element.Element; + +import org.mapstruct.ap.internal.gem.XmlElementDeclGem; +import org.mapstruct.ap.internal.gem.XmlElementRefGem; +import org.mapstruct.ap.internal.util.TypeUtils; + +/** + * The concrete implementation of the {@link XmlElementDeclSelector} that + * works with {@link javax.xml.bind.annotation.XmlElementRef} and + * {@link javax.xml.bind.annotation.XmlElementDecl}. + * + * @author Iaroslav Bogdanchikov + */ +class JavaxXmlElementDeclSelector extends XmlElementDeclSelector { + + JavaxXmlElementDeclSelector(TypeUtils typeUtils) { + super( typeUtils ); + } + + @Override + XmlElementDeclInfo getXmlElementDeclInfo(Element element) { + XmlElementDeclGem gem = XmlElementDeclGem.instanceOn( element ); + + if ( gem == null ) { + return null; + } + + return new XmlElementDeclInfo( gem.name().get(), gem.scope().get() ); + } + + @Override + XmlElementRefInfo getXmlElementRefInfo(Element element) { + XmlElementRefGem gem = XmlElementRefGem.instanceOn( element ); + + if ( gem == null ) { + return null; + } + + return new XmlElementRefInfo( gem.name().get(), gem.type().get() ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/LifecycleOverloadDeduplicateSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/LifecycleOverloadDeduplicateSelector.java new file mode 100644 index 0000000000..7ce23af186 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/LifecycleOverloadDeduplicateSelector.java @@ -0,0 +1,129 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.selector; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.stream.Collectors; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.ParameterBinding; +import org.mapstruct.ap.internal.model.source.Method; + +/** + * Selector for deduplicating overloaded lifecycle callback methods + * whose parameter signatures differ only by type hierarchy. + *

    + * In the context of lifecycle callback method selection + * (such as @BeforeMapping or @AfterMapping), it is possible to have multiple overloaded methods + * whose parameter lists are structurally identical except for the specific types, + * where those types are related by inheritance (e.g., one parameter is a superclass or subclass of another). + *

    + * This selector groups such methods by their effective parameter signature + * (ignoring differences only in type hierarchy), and, within each group, + * retains only the method whose parameter types have the closest inheritance distance + * to the actual invocation types. + * This ensures that, for each group of nearly identical overloads, + * only the most specific and appropriate method is selected. + *

    + * Example (see Issue3849Test): + * + *

    {@code
    + * @AfterMapping
    + * default void afterMapping(Parent source, @MappingTarget ParentDto target) { ... }
    + * @AfterMapping
    + * default void afterMapping(Parent source, @MappingTarget ChildDto target) { ... }
    + * }
    + * When mapping a Child to a ChildDto, + * only the method with ChildDto is selected, even though both methods match by signature + * except for the target type's inheritance relationship. + */ +public class LifecycleOverloadDeduplicateSelector implements MethodSelector { + @Override + public List> getMatchingMethods(List> methods, + SelectionContext context) { + if ( !context.getSelectionCriteria().isLifecycleCallbackRequired() || methods.size() <= 1 ) { + return methods; + } + Collection>> methodSignatureGroups = + methods.stream() + .collect( Collectors.groupingBy( + LifecycleOverloadDeduplicateSelector::buildSignatureKey, + LinkedHashMap::new, + Collectors.toList() + ) ) + .values(); + List> deduplicatedMethods = new ArrayList<>( methods.size() ); + for ( List> signatureGroup : methodSignatureGroups ) { + if ( signatureGroup.size() == 1 ) { + deduplicatedMethods.add( signatureGroup.get( 0 ) ); + continue; + } + SelectedMethod bestInheritanceMethod = signatureGroup.get( 0 ); + for ( int i = 1; i < signatureGroup.size(); i++ ) { + SelectedMethod candidateMethod = signatureGroup.get( i ); + if ( isInheritanceBetter( candidateMethod, bestInheritanceMethod ) ) { + bestInheritanceMethod = candidateMethod; + } + } + deduplicatedMethods.add( bestInheritanceMethod ); + } + return deduplicatedMethods; + } + + /** + * Builds a grouping key for a method based on its defining type, + * method name, and a detailed breakdown of each parameter binding. + *

    + * The key consists of: + *

      + *
    • The type that defines the method
    • + *
    • The method name
    • + *
    • parameter bindings
    • + *
    + * This ensures that methods are grouped together only if all these aspects match, + * except for differences in type hierarchy, which are handled separately. + */ + private static List buildSignatureKey(SelectedMethod method) { + List key = new ArrayList<>(); + key.add( method.getMethod().getDefiningType() ); + key.add( method.getMethod().getName() ); + for ( ParameterBinding binding : method.getParameterBindings() ) { + key.add( binding.getType() ); + key.add( binding.getVariableName() ); + } + return key; + } + + /** + * Compare the inheritance distance of parameters between two methods to determine if candidateMethod is better. + * Compares parameters in order, returns as soon as a better one is found. + */ + private boolean isInheritanceBetter(SelectedMethod candidateMethod, + SelectedMethod currentBestMethod) { + List candidateBindings = candidateMethod.getParameterBindings(); + List bestBindings = currentBestMethod.getParameterBindings(); + List candidateParams = candidateMethod.getMethod().getParameters(); + List bestParams = currentBestMethod.getMethod().getParameters(); + int paramCount = candidateBindings.size(); + + for ( int i = 0; i < paramCount; i++ ) { + int candidateDistance = candidateBindings.get( i ) + .getType() + .distanceTo( candidateParams.get( i ).getType() ); + int bestDistance = bestBindings.get( i ).getType().distanceTo( bestParams.get( i ).getType() ); + if ( candidateDistance < bestDistance ) { + return true; + } + else if ( candidateDistance > bestDistance ) { + return false; + } + } + return false; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodFamilySelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodFamilySelector.java index ff85bc062a..691199b49d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodFamilySelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodFamilySelector.java @@ -1,27 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.ArrayList; import java.util.List; -import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.gem.ConditionStrategyGem; import org.mapstruct.ap.internal.model.source.Method; /** @@ -33,15 +20,29 @@ public class MethodFamilySelector implements MethodSelector { @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, - Type targetType, SelectionCriteria criteria) { + public List> getMatchingMethods(List> methods, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); - List> result = new ArrayList>( methods.size() ); + List> result = new ArrayList<>( methods.size() ); for ( SelectedMethod method : methods ) { - if ( method.getMethod().isObjectFactory() == criteria.isObjectFactoryRequired() - && method.getMethod().isLifecycleCallbackMethod() == criteria.isLifecycleCallbackRequired() ) { + if ( criteria.isPresenceCheckRequired() ) { + if ( method.getMethod() + .getConditionOptions() + .isStrategyApplicable( ConditionStrategyGem.PROPERTIES ) ) { + result.add( method ); + } + } + else if ( criteria.isSourceParameterCheckRequired() ) { + if ( method.getMethod() + .getConditionOptions() + .isStrategyApplicable( ConditionStrategyGem.SOURCE_PARAMETERS ) ) { + result.add( method ); + } + } + else if ( method.getMethod().isObjectFactory() == criteria.isObjectFactoryRequired() + && method.getMethod().isLifecycleCallbackMethod() == criteria.isLifecycleCallbackRequired() + ) { result.add( method ); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelector.java index 351c71b35d..375d5a9bf8 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelector.java @@ -1,26 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.List; -import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; /** @@ -36,15 +22,10 @@ interface MethodSelector { * Selects those methods which match the given types and other criteria * * @param either SourceMethod or BuiltInMethod - * @param mappingMethod mapping method, defined in Mapper for which this selection is carried out * @param candidates list of available methods - * @param sourceTypes parameter type(s) that should be matched - * @param targetType result type that should be matched - * @param criteria criteria used in the selection process + * @param context the context for the matching * @return list of methods that passes the matching process */ - List> getMatchingMethods(Method mappingMethod, - List> candidates, - List sourceTypes, - Type targetType, SelectionCriteria criteria); + List> getMatchingMethods(List> candidates, + SelectionContext context); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java index 1495b3e6e0..774f25a8c3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MethodSelectors.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; @@ -22,12 +9,11 @@ import java.util.Arrays; import java.util.List; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.option.Options; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.TypeUtils; /** * Applies all known {@link MethodSelector}s in order. @@ -38,45 +24,48 @@ public class MethodSelectors { private final List selectors; - public MethodSelectors(Types typeUtils, Elements elementUtils, TypeFactory typeFactory) { - selectors = Arrays.asList( + public MethodSelectors(TypeUtils typeUtils, ElementUtils elementUtils, + FormattingMessager messager, Options options) { + List selectorList = new ArrayList<>( Arrays.asList( new MethodFamilySelector(), - new TypeSelector( typeFactory ), + new TypeSelector( messager ), new QualifierSelector( typeUtils, elementUtils ), - new TargetTypeSelector( typeUtils, elementUtils ), - new XmlElementDeclSelector( typeUtils ), - new InheritanceSelector(), + new TargetTypeSelector( typeUtils ), + new JavaxXmlElementDeclSelector( typeUtils ), + new JakartaXmlElementDeclSelector( typeUtils ), + new InheritanceSelector() + ) ); + if ( options != null && !options.isDisableLifecycleOverloadDeduplicateSelector() ) { + selectorList.add( new LifecycleOverloadDeduplicateSelector() ); + } + + selectorList.addAll( Arrays.asList( new CreateOrUpdateSelector(), - new FactoryParameterSelector() ); + new SourceRhsSelector(), + new FactoryParameterSelector(), + new MostSpecificResultTypeSelector() + ) ); + this.selectors = selectorList; } /** * Selects those methods which match the given types and other criteria * * @param either SourceMethod or BuiltInMethod - * @param mappingMethod mapping method, defined in Mapper for which this selection is carried out * @param methods list of available methods - * @param sourceTypes parameter type(s) that should be matched - * @param targetType return type that should be matched - * @param criteria criteria used in the selection process + * @param context the selection context that should be used in the matching process * @return list of methods that passes the matching process */ - public List> getMatchingMethods(Method mappingMethod, List methods, - List sourceTypes, Type targetType, - SelectionCriteria criteria) { + public List> getMatchingMethods(List methods, + SelectionContext context) { - List> candidates = new ArrayList>( methods.size() ); + List> candidates = new ArrayList<>( methods.size() ); for ( T method : methods ) { - candidates.add( new SelectedMethod( method ) ); + candidates.add( new SelectedMethod<>( method ) ); } for ( MethodSelector selector : selectors ) { - candidates = selector.getMatchingMethods( - mappingMethod, - candidates, - sourceTypes, - targetType, - criteria ); + candidates = selector.getMatchingMethods( candidates, context ); } return candidates; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MostSpecificResultTypeSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MostSpecificResultTypeSelector.java new file mode 100644 index 0000000000..88e302eba0 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/MostSpecificResultTypeSelector.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.selector; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.source.Method; + +/** + * A {@link MethodSelector} that selects the most specific result type. + * + * @author Filip Hrisafov + */ +public class MostSpecificResultTypeSelector implements MethodSelector { + + @Override + public List> getMatchingMethods(List> candidates, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); + Type mappingTargetType = context.getMappingTargetType(); + if ( candidates.size() < 2 || !criteria.isForMapping() || criteria.getQualifyingResultType() != null ) { + return candidates; + } + + List> result = new ArrayList<>(); + + for ( SelectedMethod candidate : candidates ) { + if ( candidate.getMethod() + .getResultType() + .getBoxedEquivalent() + .equals( mappingTargetType.getBoxedEquivalent() ) ) { + // If the result type is the same as the target type + // then this candidate has the most specific match and should be used + result.add( candidate ); + } + } + + + // If not most specific types were found then return the current candidates + return result.isEmpty() ? candidates : result; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/QualifierSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/QualifierSelector.java index 5a32375697..744c03d77c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/QualifierSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/QualifierSelector.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; @@ -22,18 +9,17 @@ import java.util.HashSet; import java.util.List; import java.util.Set; - import javax.lang.model.element.AnnotationMirror; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.gem.NamedGem; +import org.mapstruct.ap.internal.gem.QualifierGem; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SourceMethod; -import org.mapstruct.ap.internal.prism.NamedPrism; -import org.mapstruct.ap.internal.prism.QualifierPrism; +import org.mapstruct.ap.internal.util.ElementUtils; +import org.mapstruct.ap.internal.util.TypeUtils; /** * This selector selects a best match based on qualifier annotations. @@ -54,29 +40,28 @@ */ public class QualifierSelector implements MethodSelector { - private final Types typeUtils; + private final TypeUtils typeUtils; private final TypeMirror namedAnnotationTypeMirror; - public QualifierSelector( Types typeUtils, Elements elementUtils ) { + public QualifierSelector(TypeUtils typeUtils, ElementUtils elementUtils ) { this.typeUtils = typeUtils; namedAnnotationTypeMirror = elementUtils.getTypeElement( "org.mapstruct.Named" ).asType(); } @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, Type targetType, - SelectionCriteria criteria) { + public List> getMatchingMethods(List> methods, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); int numberOfQualifiersToMatch = 0; // Define some local collections and make sure that they are defined. - List qualifierTypes = new ArrayList(); + List qualifierTypes = new ArrayList<>(); if ( criteria.getQualifiers() != null ) { qualifierTypes.addAll( criteria.getQualifiers() ); numberOfQualifiersToMatch += criteria.getQualifiers().size(); } - List qualfiedByNames = new ArrayList(); + List qualfiedByNames = new ArrayList<>(); if ( criteria.getQualifiedByNames() != null ) { qualfiedByNames.addAll( criteria.getQualifiedByNames() ); numberOfQualifiersToMatch += criteria.getQualifiedByNames().size(); @@ -90,7 +75,7 @@ public List> getMatchingMethods(Method mapp // Check there are qualfiers for this mapping: Mapping#qualifier or Mapping#qualfiedByName if ( qualifierTypes.isEmpty() ) { // When no qualifiers, disqualify all methods marked with a qualifier by removing them from the candidates - List> nonQualiferAnnotatedMethods = new ArrayList>( methods.size() ); + List> nonQualiferAnnotatedMethods = new ArrayList<>( methods.size() ); for ( SelectedMethod candidate : methods ) { if ( candidate.getMethod() instanceof SourceMethod ) { @@ -108,7 +93,7 @@ public List> getMatchingMethods(Method mapp } else { // Check all methods marked with qualfier (or methods in Mappers marked wiht a qualfier) for matches. - List> matches = new ArrayList>( methods.size() ); + List> matches = new ArrayList<>( methods.size() ); for ( SelectedMethod candidate : methods ) { if ( !( candidate.getMethod() instanceof SourceMethod ) ) { @@ -124,14 +109,14 @@ public List> getMatchingMethods(Method mapp for ( AnnotationMirror qualifierAnnotationMirror : qualifierAnnotationMirrors ) { for ( TypeMirror qualifierType : qualifierTypes ) { - // get the type of the annotation mirror. + // get the type of the annotation positionHint. DeclaredType qualifierAnnotationType = qualifierAnnotationMirror.getAnnotationType(); if ( typeUtils.isSameType( qualifierType, qualifierAnnotationType ) ) { // Match! we have an annotation which has the @Qualifer marker ( could be @Named as well ) if ( typeUtils.isSameType( qualifierAnnotationType, namedAnnotationTypeMirror ) ) { // Match! its an @Named, so do the additional check on name. - NamedPrism namedPrism = NamedPrism.getInstance( qualifierAnnotationMirror ); - if ( namedPrism.value() != null && qualfiedByNames.contains( namedPrism.value() ) ) { + NamedGem named = NamedGem.instanceOn( qualifierAnnotationMirror ); + if ( named.value().hasValue() && qualfiedByNames.contains( named.value().get() ) ) { // Match! its an @Name and the value matches as well. Oh boy. matchingQualifierCounter++; } @@ -151,19 +136,14 @@ public List> getMatchingMethods(Method mapp matches.add( candidate ); } } - if ( !matches.isEmpty() ) { - return matches; - } - else { - return methods; - } + return matches; } } private Set getQualifierAnnotationMirrors( Method candidate ) { // retrieve annotations - Set qualiferAnnotations = new HashSet(); + Set qualiferAnnotations = new HashSet<>(); // first from the method itself SourceMethod candidateSM = (SourceMethod) candidate; @@ -186,7 +166,7 @@ private Set getQualifierAnnotationMirrors( Method candidate ) private void addOnlyWhenQualifier( Set annotationSet, AnnotationMirror candidate ) { // only add the candidate annotation when the candidate itself has the annotation 'Qualifier' - if ( QualifierPrism.getInstanceOn( candidate.getAnnotationType().asElement() ) != null ) { + if ( QualifierGem.instanceOn( candidate.getAnnotationType().asElement() ) != null ) { annotationSet.add( candidate ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectedMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectedMethod.java index 00eac7e302..1702a8d4d6 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectedMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectedMethod.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.List; +import java.util.Objects; import org.mapstruct.ap.internal.model.common.ParameterBinding; import org.mapstruct.ap.internal.model.source.Method; @@ -26,6 +14,8 @@ /** * A selected method with additional metadata that might be required for further usage of the selected method. * + * @param the type of the method + * * @author Andreas Gudian */ public class SelectedMethod { @@ -52,4 +42,21 @@ public void setParameterBindings(List parameterBindings) { public String toString() { return method.toString(); } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SelectedMethod that = (SelectedMethod) o; + return method.equals( that.method ); + } + + @Override + public int hashCode() { + return Objects.hash( method ); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionContext.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionContext.java new file mode 100644 index 0000000000..79351ae868 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionContext.java @@ -0,0 +1,302 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.selector; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Supplier; + +import org.mapstruct.ap.internal.model.common.Parameter; +import org.mapstruct.ap.internal.model.common.ParameterBinding; +import org.mapstruct.ap.internal.model.common.SourceRHS; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.common.TypeFactory; +import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.model.source.SelectionParameters; + +/** + * Context passed to the selectors to get the information they need. + * + * @author Filip Hrisafov + */ +public class SelectionContext { + + private final Type sourceType; + private final SelectionCriteria selectionCriteria; + private final Method mappingMethod; + private final Type mappingTargetType; + private final Type returnType; + private final Supplier> parameterBindingsProvider; + private List parameterBindings; + + private SelectionContext(Type sourceType, SelectionCriteria selectionCriteria, Method mappingMethod, + Type mappingTargetType, Type returnType, + Supplier> parameterBindingsProvider) { + this.sourceType = sourceType; + this.selectionCriteria = selectionCriteria; + this.mappingMethod = mappingMethod; + this.mappingTargetType = mappingTargetType; + this.returnType = returnType; + this.parameterBindingsProvider = parameterBindingsProvider; + } + + /** + * @return the source type that should be matched + */ + public Type getSourceType() { + return sourceType; + } + + /** + * @return the criteria used in the selection process + */ + public SelectionCriteria getSelectionCriteria() { + return selectionCriteria; + } + + /** + * @return the mapping target type that should be matched + */ + public Type getMappingTargetType() { + return mappingTargetType; + } + + /** + * @return the return type that should be matched + */ + public Type getReturnType() { + return returnType; + } + + /** + * @return the available parameter bindings for the matching + */ + public List getAvailableParameterBindings() { + if ( this.parameterBindings == null ) { + this.parameterBindings = this.parameterBindingsProvider.get(); + } + return parameterBindings; + } + + /** + * @return the mapping method, defined in Mapper for which this selection is carried out + */ + public Method getMappingMethod() { + return mappingMethod; + } + + public static SelectionContext forMappingMethods(Method mappingMethod, Type source, Type target, + SelectionCriteria criteria, TypeFactory typeFactory) { + return new SelectionContext( + source, + criteria, + mappingMethod, + target, + target, + () -> getAvailableParameterBindingsFromSourceType( + source, + target, + mappingMethod, + typeFactory + ) + ); + } + + public static SelectionContext forLifecycleMethods(Method mappingMethod, Type targetType, + SelectionParameters selectionParameters, + TypeFactory typeFactory, + Supplier> additionalParameterBindingsProvider) { + SelectionCriteria criteria = SelectionCriteria.forLifecycleMethods( selectionParameters ); + return new SelectionContext( + null, + criteria, + mappingMethod, + targetType, + mappingMethod.getResultType(), + () -> { + List parameterBindings = getAvailableParameterBindingsFromMethod( + mappingMethod, + targetType, + criteria.getSourceRHS(), + typeFactory + ); + parameterBindings.addAll( additionalParameterBindingsProvider.get() ); + return parameterBindings; + } + ); + } + + public static SelectionContext forFactoryMethods(Method mappingMethod, Type alternativeTarget, + SelectionParameters selectionParameters, + TypeFactory typeFactory) { + SelectionCriteria criteria = SelectionCriteria.forFactoryMethods( selectionParameters ); + return new SelectionContext( + null, + criteria, + mappingMethod, + alternativeTarget, + alternativeTarget, + () -> getAvailableParameterBindingsFromMethod( + mappingMethod, + alternativeTarget, + criteria.getSourceRHS(), + typeFactory + ) + ); + } + + public static SelectionContext forPresenceCheckMethods(Method mappingMethod, + SelectionParameters selectionParameters, + TypeFactory typeFactory) { + SelectionCriteria criteria = SelectionCriteria.forPresenceCheckMethods( selectionParameters ); + Type booleanType = typeFactory.getType( Boolean.class ); + return new SelectionContext( + null, + criteria, + mappingMethod, + booleanType, + booleanType, + () -> getAvailableParameterBindingsFromMethod( + mappingMethod, + booleanType, + criteria.getSourceRHS(), + typeFactory + ) + ); + } + + public static SelectionContext forSourceParameterPresenceCheckMethods(Method mappingMethod, + SelectionParameters selectionParameters, + Parameter sourceParameter, + TypeFactory typeFactory) { + SelectionCriteria criteria = SelectionCriteria.forSourceParameterCheckMethods( selectionParameters ); + Type booleanType = typeFactory.getType( Boolean.class ); + return new SelectionContext( + null, + criteria, + mappingMethod, + booleanType, + booleanType, + () -> getParameterBindingsForSourceParameterPresenceCheck( + mappingMethod, + booleanType, + sourceParameter, + typeFactory + ) + ); + } + + private static List getParameterBindingsForSourceParameterPresenceCheck(Method method, + Type targetType, + Parameter sourceParameter, + TypeFactory typeFactory) { + + List availableParams = new ArrayList<>( method.getParameters().size() + 3 ); + + availableParams.add( ParameterBinding.fromParameter( sourceParameter ) ); + availableParams.add( ParameterBinding.forTargetTypeBinding( typeFactory.classTypeOf( targetType ) ) ); + for ( Parameter parameter : method.getParameters() ) { + if ( !parameter.isSourceParameter( ) ) { + availableParams.add( ParameterBinding.fromParameter( parameter ) ); + } + } + + return availableParams; + } + + private static List getAvailableParameterBindingsFromMethod(Method method, Type targetType, + SourceRHS sourceRHS, + TypeFactory typeFactory) { + List availableParams = new ArrayList<>( method.getParameters().size() + 3 ); + + if ( sourceRHS != null ) { + availableParams.addAll( ParameterBinding.fromParameters( method.getParameters() ) ); + availableParams.add( ParameterBinding.fromSourceRHS( sourceRHS ) ); + addSourcePropertyNameBindings( availableParams, sourceRHS.getSourceType(), typeFactory ); + } + else { + availableParams.addAll( ParameterBinding.fromParameters( method.getParameters() ) ); + } + + addTargetRelevantBindings( availableParams, targetType, typeFactory ); + + return availableParams; + } + + private static List getAvailableParameterBindingsFromSourceType(Type sourceType, + Type targetType, + Method mappingMethod, + TypeFactory typeFactory) { + + List availableParams = new ArrayList<>(); + + availableParams.add( ParameterBinding.forSourceTypeBinding( sourceType ) ); + addSourcePropertyNameBindings( availableParams, sourceType, typeFactory ); + + for ( Parameter param : mappingMethod.getParameters() ) { + if ( param.isMappingContext() ) { + availableParams.add( ParameterBinding.fromParameter( param ) ); + } + } + + addTargetRelevantBindings( availableParams, targetType, typeFactory ); + + return availableParams; + } + + private static void addSourcePropertyNameBindings(List availableParams, Type sourceType, + TypeFactory typeFactory) { + + boolean sourcePropertyNameAvailable = false; + for ( ParameterBinding pb : availableParams ) { + if ( pb.isSourcePropertyName() ) { + sourcePropertyNameAvailable = true; + break; + } + } + if ( !sourcePropertyNameAvailable ) { + availableParams.add( ParameterBinding.forSourcePropertyNameBinding( typeFactory.getType( String.class ) ) ); + } + + } + + /** + * Adds default parameter bindings for the mapping-target and target-type if not already available. + * + * @param availableParams Already available params, new entries will be added to this list + * @param targetType Target type + */ + private static void addTargetRelevantBindings(List availableParams, Type targetType, + TypeFactory typeFactory) { + boolean mappingTargetAvailable = false; + boolean targetTypeAvailable = false; + boolean targetPropertyNameAvailable = false; + + // search available parameter bindings if mapping-target and/or target-type is available + for ( ParameterBinding pb : availableParams ) { + if ( pb.isMappingTarget() ) { + mappingTargetAvailable = true; + } + else if ( pb.isTargetType() ) { + targetTypeAvailable = true; + } + else if ( pb.isTargetPropertyName() ) { + targetPropertyNameAvailable = true; + } + } + + if ( !mappingTargetAvailable ) { + availableParams.add( ParameterBinding.forMappingTargetBinding( targetType ) ); + } + if ( !targetTypeAvailable ) { + availableParams.add( ParameterBinding.forTargetTypeBinding( typeFactory.classTypeOf( targetType ) ) ); + } + if ( !targetPropertyNameAvailable ) { + availableParams.add( ParameterBinding.forTargetPropertyNameBinding( typeFactory.getType( String.class ) ) ); + } + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionCriteria.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionCriteria.java index 9856dd9281..45e11fe6ea 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionCriteria.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SelectionCriteria.java @@ -1,29 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; - import javax.lang.model.type.TypeMirror; import org.mapstruct.ap.internal.model.common.SourceRHS; +import org.mapstruct.ap.internal.model.source.MappingControl; import org.mapstruct.ap.internal.model.source.SelectionParameters; /** @@ -33,54 +20,79 @@ */ public class SelectionCriteria { - private final List qualifiers = new ArrayList(); - private final List qualifiedByNames = new ArrayList(); + private final QualifyingInfo qualifyingInfo; private final String targetPropertyName; - private final TypeMirror qualifyingResultType; private final SourceRHS sourceRHS; - private boolean preferUpdateMapping; - private final boolean objectFactoryRequired; - private final boolean lifecycleCallbackRequired; - - public SelectionCriteria(SelectionParameters selectionParameters, String targetPropertyName, - boolean preferUpdateMapping, boolean objectFactoryRequired, - boolean lifecycleCallbackRequired) { - if ( selectionParameters != null ) { - qualifiers.addAll( selectionParameters.getQualifiers() ); - qualifiedByNames.addAll( selectionParameters.getQualifyingNames() ); - qualifyingResultType = selectionParameters.getResultType(); - sourceRHS = selectionParameters.getSourceRHS(); - } - else { - this.qualifyingResultType = null; - sourceRHS = null; - } + private boolean ignoreQualifiers = false; + private Type type; + private final MappingControl mappingControl; + + public SelectionCriteria(SelectionParameters selectionParameters, MappingControl mappingControl, + String targetPropertyName, Type type) { + this( + QualifyingInfo.fromSelectionParameters( selectionParameters ), + selectionParameters != null ? selectionParameters.getSourceRHS() : null, + mappingControl, + targetPropertyName, + type + ); + } + + private SelectionCriteria(QualifyingInfo qualifyingInfo, SourceRHS sourceRHS, MappingControl mappingControl, + String targetPropertyName, Type type) { + this.qualifyingInfo = qualifyingInfo; this.targetPropertyName = targetPropertyName; - this.preferUpdateMapping = preferUpdateMapping; - this.objectFactoryRequired = objectFactoryRequired; - this.lifecycleCallbackRequired = lifecycleCallbackRequired; + this.sourceRHS = sourceRHS; + this.type = type; + this.mappingControl = mappingControl; + } + + /** + * + * @return {@code true} if only mapping methods should be selected + */ + public boolean isForMapping() { + return type == null || type == Type.PREFER_UPDATE_MAPPING; } /** * @return true if factory methods should be selected, false otherwise. */ public boolean isObjectFactoryRequired() { - return objectFactoryRequired; + return type == Type.OBJECT_FACTORY; } /** * @return true if lifecycle callback methods should be selected, false otherwise. */ public boolean isLifecycleCallbackRequired() { - return lifecycleCallbackRequired; + return type == Type.LIFECYCLE_CALLBACK; + } + + /** + * @return {@code true} if presence check methods should be selected, {@code false} otherwise + */ + public boolean isPresenceCheckRequired() { + return type == Type.PRESENCE_CHECK; + } + + /** + * @return {@code true} if source parameter check methods should be selected, {@code false} otherwise + */ + public boolean isSourceParameterCheckRequired() { + return type == Type.SOURCE_PARAMETER_CHECK; + } + + public void setIgnoreQualifiers(boolean ignoreQualifiers) { + this.ignoreQualifiers = ignoreQualifiers; } public List getQualifiers() { - return qualifiers; + return ignoreQualifiers ? Collections.emptyList() : qualifyingInfo.qualifiers(); } public List getQualifiedByNames() { - return qualifiedByNames; + return ignoreQualifiers ? Collections.emptyList() : qualifyingInfo.qualifiedByNames(); } public String getTargetPropertyName() { @@ -88,11 +100,11 @@ public String getTargetPropertyName() { } public TypeMirror getQualifyingResultType() { - return qualifyingResultType; + return qualifyingInfo.qualifyingResultType(); } public boolean isPreferUpdateMapping() { - return preferUpdateMapping; + return type == Type.PREFER_UPDATE_MAPPING; } public SourceRHS getSourceRHS() { @@ -100,20 +112,131 @@ public SourceRHS getSourceRHS() { } public void setPreferUpdateMapping(boolean preferUpdateMapping) { - this.preferUpdateMapping = preferUpdateMapping; + this.type = preferUpdateMapping ? Type.PREFER_UPDATE_MAPPING : null; + } + + public boolean hasQualfiers() { + return !qualifyingInfo.qualifiedByNames().isEmpty() || !qualifyingInfo.qualifiers().isEmpty(); + } + + public boolean isAllowDirect() { + return mappingControl == null || mappingControl.allowDirect(); + } + + public boolean isAllowConversion() { + return mappingControl == null || mappingControl.allowTypeConversion(); + } + + public boolean isAllowMappingMethod() { + return mappingControl == null || mappingControl.allowMappingMethod(); + } + + public boolean isAllow2Steps() { + return mappingControl == null || mappingControl.allowBy2Steps(); + } + + public boolean isSelfAllowed() { + return type != Type.SELF_NOT_ALLOWED; } public static SelectionCriteria forMappingMethods(SelectionParameters selectionParameters, + MappingControl mappingControl, String targetPropertyName, boolean preferUpdateMapping) { - return new SelectionCriteria( selectionParameters, targetPropertyName, preferUpdateMapping, false, false ); + return new SelectionCriteria( + selectionParameters, + mappingControl, + targetPropertyName, + preferUpdateMapping ? Type.PREFER_UPDATE_MAPPING : null + ); } public static SelectionCriteria forFactoryMethods(SelectionParameters selectionParameters) { - return new SelectionCriteria( selectionParameters, null, false, true, false ); + return new SelectionCriteria( selectionParameters, null, null, Type.OBJECT_FACTORY ); } public static SelectionCriteria forLifecycleMethods(SelectionParameters selectionParameters) { - return new SelectionCriteria( selectionParameters, null, false, false, true ); + return new SelectionCriteria( selectionParameters, null, null, Type.LIFECYCLE_CALLBACK ); + } + + public static SelectionCriteria forPresenceCheckMethods(SelectionParameters selectionParameters) { + SourceRHS sourceRHS = selectionParameters.getSourceRHS(); + Type type; + QualifyingInfo qualifyingInfo = new QualifyingInfo( + selectionParameters.getConditionQualifiers(), + selectionParameters.getConditionQualifyingNames(), + selectionParameters.getResultType() + ); + if ( sourceRHS != null && sourceRHS.isSourceReferenceParameter() ) { + // If the source reference is for a source parameter, + // then the presence check should be for the source parameter + type = Type.SOURCE_PARAMETER_CHECK; + } + else { + type = Type.PRESENCE_CHECK; + } + return new SelectionCriteria( qualifyingInfo, sourceRHS, null, null, type ); + } + + public static SelectionCriteria forSourceParameterCheckMethods(SelectionParameters selectionParameters) { + return new SelectionCriteria( selectionParameters, null, null, Type.SOURCE_PARAMETER_CHECK ); + } + + public static SelectionCriteria forSubclassMappingMethods(SelectionParameters selectionParameters, + MappingControl mappingControl) { + return new SelectionCriteria( selectionParameters, mappingControl, null, Type.SELF_NOT_ALLOWED ); + } + + private static class QualifyingInfo { + + private static final QualifyingInfo EMPTY = new QualifyingInfo( + Collections.emptyList(), + Collections.emptyList(), + null + ); + + private final List qualifiers; + private final List qualifiedByNames; + private final TypeMirror qualifyingResultType; + + private QualifyingInfo(List qualifiers, List qualifiedByNames, + TypeMirror qualifyingResultType) { + this.qualifiers = qualifiers; + this.qualifiedByNames = qualifiedByNames; + this.qualifyingResultType = qualifyingResultType; + } + + public List qualifiers() { + return qualifiers; + } + + public List qualifiedByNames() { + return qualifiedByNames; + } + + public TypeMirror qualifyingResultType() { + return qualifyingResultType; + } + + private static QualifyingInfo fromSelectionParameters(SelectionParameters selectionParameters) { + if ( selectionParameters == null ) { + return EMPTY; + } + return new QualifyingInfo( + selectionParameters.getQualifiers(), + selectionParameters.getQualifyingNames(), + selectionParameters.getResultType() + ); + } + } + + + public enum Type { + PREFER_UPDATE_MAPPING, + OBJECT_FACTORY, + LIFECYCLE_CALLBACK, + PRESENCE_CHECK, + SOURCE_PARAMETER_CHECK, + SELF_NOT_ALLOWED, } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SourceRhsSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SourceRhsSelector.java new file mode 100644 index 0000000000..91a30902e0 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/SourceRhsSelector.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.model.source.selector; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.ap.internal.model.common.ParameterBinding; +import org.mapstruct.ap.internal.model.source.Method; + +/** + * Selector that tries to resolve an ambiguity between methods that contain source parameters and + * {@link org.mapstruct.ap.internal.model.common.SourceRHS SourceRHS} type parameters. + * @author Filip Hrisafov + */ +public class SourceRhsSelector implements MethodSelector { + + @Override + public List> getMatchingMethods(List> candidates, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); + if ( candidates.size() < 2 || criteria.getSourceRHS() == null ) { + return candidates; + } + + List> sourceRHSFavoringCandidates = new ArrayList<>(); + + for ( SelectedMethod candidate : candidates ) { + for ( ParameterBinding parameterBinding : candidate.getParameterBindings() ) { + if ( parameterBinding.getSourceRHS() != null ) { + sourceRHSFavoringCandidates.add( candidate ); + break; + } + } + + } + + if ( !sourceRHSFavoringCandidates.isEmpty() ) { + return sourceRHSFavoringCandidates; + } + + return candidates; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TargetTypeSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TargetTypeSelector.java index 7824a0acac..181c1f883b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TargetTypeSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TargetTypeSelector.java @@ -1,32 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.ArrayList; import java.util.List; - import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; -import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; +import org.mapstruct.ap.internal.util.TypeUtils; /** * This selector selects a best match based on the result type. @@ -38,23 +22,22 @@ */ public class TargetTypeSelector implements MethodSelector { - private final Types typeUtils; + private final TypeUtils typeUtils; - public TargetTypeSelector( Types typeUtils, Elements elementUtils ) { + public TargetTypeSelector( TypeUtils typeUtils ) { this.typeUtils = typeUtils; } @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, Type targetType, - SelectionCriteria criteria) { + public List> getMatchingMethods(List> methods, + SelectionContext context) { + SelectionCriteria criteria = context.getSelectionCriteria(); TypeMirror qualifyingTypeMirror = criteria.getQualifyingResultType(); if ( qualifyingTypeMirror != null && !criteria.isLifecycleCallbackRequired() ) { List> candidatesWithQualifyingTargetType = - new ArrayList>( methods.size() ); + new ArrayList<>( methods.size() ); for ( SelectedMethod method : methods ) { TypeMirror resultTypeMirror = method.getMethod().getResultType().getTypeElement().asType(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TypeSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TypeSelector.java index ce977f5664..1a2389eba1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TypeSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/TypeSelector.java @@ -1,35 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.ParameterBinding; -import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; -import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.MethodMatcher; +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; + +import static org.mapstruct.ap.internal.util.Collections.first; /** * Selects those methods from the given input set which match the given source and target types (via @@ -39,36 +27,24 @@ */ public class TypeSelector implements MethodSelector { - private TypeFactory typeFactory; + private FormattingMessager messager; - public TypeSelector(TypeFactory typeFactory) { - this.typeFactory = typeFactory; + public TypeSelector(FormattingMessager messager) { + this.messager = messager; } @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, Type targetType, - SelectionCriteria criteria) { - + public List> getMatchingMethods(List> methods, + SelectionContext context) { if ( methods.isEmpty() ) { return methods; } - List> result = new ArrayList>(); + Type returnType = context.getReturnType(); - List availableBindings; - if ( sourceTypes.isEmpty() ) { - // if no source types are given, we have a factory or lifecycle method - availableBindings = getAvailableParameterBindingsFromMethod( - mappingMethod, - targetType, - criteria.getSourceRHS() - ); - } - else { - availableBindings = getAvailableParameterBindingsFromSourceTypes( sourceTypes, targetType, mappingMethod ); - } + List> result = new ArrayList<>(); + + List availableBindings = context.getAvailableParameterBindings(); for ( SelectedMethod method : methods ) { List> parameterBindingPermutations = @@ -76,7 +52,7 @@ public List> getMatchingMethods(Method mapp if ( parameterBindingPermutations != null ) { SelectedMethod matchingMethod = - getFirstMatchingParameterBinding( targetType, method, parameterBindingPermutations ); + getMatchingParameterBinding( returnType, context, method, parameterBindingPermutations ); if ( matchingMethod != null ) { result.add( matchingMethod ); @@ -86,57 +62,91 @@ public List> getMatchingMethods(Method mapp return result; } - private List getAvailableParameterBindingsFromMethod(Method method, Type targetType, - SourceRHS sourceRHS) { - List availableParams = new ArrayList( method.getParameters().size() + 3 ); - - addMappingTargetAndTargetTypeBindings( availableParams, targetType ); - if ( sourceRHS != null ) { - availableParams.addAll( ParameterBinding.fromParameters( method.getContextParameters() ) ); - availableParams.add( ParameterBinding.fromSourceRHS( sourceRHS ) ); - } - else { - availableParams.addAll( ParameterBinding.fromParameters( method.getParameters() ) ); - } - - return availableParams; - } + private SelectedMethod getMatchingParameterBinding(Type returnType, + SelectionContext context, SelectedMethod selectedMethodInfo, + List> parameterAssignmentVariants) { - private List getAvailableParameterBindingsFromSourceTypes(List sourceTypes, - Type targetType, Method mappingMethod) { + List> matchingParameterAssignmentVariants = new ArrayList<>( + parameterAssignmentVariants + ); - List availableParams = new ArrayList( sourceTypes.size() + 2 ); + Method selectedMethod = selectedMethodInfo.getMethod(); - addMappingTargetAndTargetTypeBindings( availableParams, targetType ); + // remove all assignment variants that doesn't match the types from the method + matchingParameterAssignmentVariants.removeIf( parameterAssignments -> + !selectedMethod.matches( extractTypes( parameterAssignments ), returnType ) + ); - for ( Type sourceType : sourceTypes ) { - availableParams.add( ParameterBinding.forSourceTypeBinding( sourceType ) ); + if ( matchingParameterAssignmentVariants.isEmpty() ) { + // no matching variants found + return null; + } + else if ( matchingParameterAssignmentVariants.size() == 1 ) { + // we found exactly one set of variants, use this + selectedMethodInfo.setParameterBindings( first( matchingParameterAssignmentVariants ) ); + return selectedMethodInfo; } - for ( Parameter param : mappingMethod.getParameters() ) { - if ( param.isMappingContext() ) { - availableParams.add( ParameterBinding.fromParameter( param ) ); - } + // more than one variant matches, try to find one where also the parameter names are matching + // -> remove all variants where the binding var-name doesn't match the var-name of the parameter + List methodParameters = selectedMethod.getParameters(); + + matchingParameterAssignmentVariants.removeIf( parameterBindings -> + parameterBindingNotMatchesParameterVariableNames( + parameterBindings, + methodParameters + ) + ); + + + if ( matchingParameterAssignmentVariants.isEmpty() ) { + // we had some matching assignments before, but when checking the parameter names we can't find an + // appropriate one, in this case the user must chose identical parameter names for the mapping and lifecycle + // method + messager.printMessage( + selectedMethod.getExecutable(), + Message.LIFECYCLEMETHOD_AMBIGUOUS_PARAMETERS, + context.getMappingMethod() + ); + + return null; } - return availableParams; + // there should never be more then one assignment left after checking the parameter names as it is not possible + // to use the same parameter name more then once + // -> we can use the first variant that is left (that should also be the only one) + selectedMethodInfo.setParameterBindings( first( matchingParameterAssignmentVariants ) ); + return selectedMethodInfo; } - private void addMappingTargetAndTargetTypeBindings(List availableParams, Type targetType) { - availableParams.add( ParameterBinding.forMappingTargetBinding( targetType ) ); - availableParams.add( ParameterBinding.forTargetTypeBinding( typeFactory.classTypeOf( targetType ) ) ); - } + /** + * Checks if the given parameter-bindings have the same variable name than the given parameters.
    + * The first entry in the parameter-bindings belongs to the first entry in the parameters and so on.
    + * + * @param parameterBindings List of parameter bindings + * @param parameters List of parameters, must have the same size than the {@code parameterBindings} list + * + * @return {@code true} as soon as there is a parameter with a different variable name than the binding + */ + private boolean parameterBindingNotMatchesParameterVariableNames(List parameterBindings, + List parameters) { + if ( parameterBindings.size() != parameters.size() ) { + return true; + } - private SelectedMethod getFirstMatchingParameterBinding(Type targetType, - SelectedMethod method, List> parameterAssignmentVariants) { + int i = 0; + for ( ParameterBinding parameterBinding : parameterBindings ) { + Parameter parameter = parameters.get( i++ ); - for ( List parameterAssignments : parameterAssignmentVariants ) { - if ( method.getMethod().matches( extractTypes( parameterAssignments ), targetType ) ) { - method.setParameterBindings( parameterAssignments ); - return method; + // if the parameterBinding contains a parameter name we must ensure that this matches the name from the + // method parameter -> remove all variants where this is not the case + if ( parameterBinding.getVariableName() != null && + !parameter.getName().equals( parameterBinding.getVariableName() ) ) { + return true; } } - return null; + + return false; } /** @@ -152,8 +162,8 @@ private static List> getCandidateParameterBindingPermutat return null; } - List> bindingPermutations = new ArrayList>( 1 ); - bindingPermutations.add( new ArrayList( methodParameters.size() ) ); + List> bindingPermutations = new ArrayList<>( 1 ); + bindingPermutations.add( new ArrayList<>( methodParameters.size() ) ); for ( Parameter methodParam : methodParameters ) { List candidateBindings = @@ -172,12 +182,12 @@ private static List> getCandidateParameterBindingPermutat } else { List> newVariants = - new ArrayList>( bindingPermutations.size() * candidateBindings.size() ); + new ArrayList<>( bindingPermutations.size() * candidateBindings.size() ); for ( List variant : bindingPermutations ) { // create a copy of each variant for each binding for ( ParameterBinding binding : candidateBindings ) { List extendedVariant = - new ArrayList( methodParameters.size() ); + new ArrayList<>( methodParameters.size() ); extendedVariant.addAll( variant ); extendedVariant.add( binding ); @@ -199,12 +209,14 @@ private static List> getCandidateParameterBindingPermutat */ private static List findCandidateBindingsForParameter(List candidateParameters, Parameter parameter) { - List result = new ArrayList( candidateParameters.size() ); + List result = new ArrayList<>( candidateParameters.size() ); for ( ParameterBinding candidate : candidateParameters ) { if ( parameter.isTargetType() == candidate.isTargetType() && parameter.isMappingTarget() == candidate.isMappingTarget() - && parameter.isMappingContext() == candidate.isMappingContext() ) { + && parameter.isMappingContext() == candidate.isMappingContext() + && parameter.isSourcePropertyName() == candidate.isSourcePropertyName() + && parameter.isTargetPropertyName() == candidate.isTargetPropertyName() ) { result.add( candidate ); } } @@ -213,12 +225,8 @@ private static List findCandidateBindingsForParameter(List extractTypes(List parameters) { - List result = new ArrayList( parameters.size() ); - - for ( ParameterBinding param : parameters ) { - result.add( param.getType() ); - } - - return result; + return parameters.stream() + .map( ParameterBinding::getType ) + .collect( Collectors.toList() ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java index ad35d691b4..a32cb250d5 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/XmlElementDeclSelector.java @@ -1,43 +1,27 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source.selector; import java.util.ArrayList; import java.util.List; - import javax.lang.model.element.Element; import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SourceMethod; -import org.mapstruct.ap.internal.prism.XmlElementDeclPrism; -import org.mapstruct.ap.internal.prism.XmlElementRefPrism; +import org.mapstruct.ap.internal.util.TypeUtils; /** - * Finds the {@link javax.xml.bind.annotation.XmlElementRef} annotation on a field (of the mapping result type or its + * Finds the {@code XmlElementRef} annotation on a field (of the mapping result type or its * super types) matching the * target property name. Then selects those methods with matching {@code name} and {@code scope} attributes of the - * {@link javax.xml.bind.annotation.XmlElementDecl} annotation, if that is present. Matching happens in the following + * {@code XmlElementDecl} annotation, if that is present. Matching happens in the following * order: *
      *
    1. Name and Scope matches
    2. @@ -48,26 +32,29 @@ * the given method is not annotated with {@code XmlElementDecl} it will be considered as matching. * * @author Sjaak Derksen + * + * @see JavaxXmlElementDeclSelector + * @see JakartaXmlElementDeclSelector */ -public class XmlElementDeclSelector implements MethodSelector { +abstract class XmlElementDeclSelector implements MethodSelector { - private final Types typeUtils; + private final TypeUtils typeUtils; - public XmlElementDeclSelector(Types typeUtils) { + XmlElementDeclSelector(TypeUtils typeUtils) { this.typeUtils = typeUtils; } @Override - public List> getMatchingMethods(Method mappingMethod, - List> methods, - List sourceTypes, Type targetType, - SelectionCriteria criteria) { - - List> nameMatches = new ArrayList>(); - List> scopeMatches = new ArrayList>(); - List> nameAndScopeMatches = new ArrayList>(); + public List> getMatchingMethods(List> methods, + SelectionContext context) { + Type resultType = context.getMappingMethod().getResultType(); + String targetPropertyName = context.getSelectionCriteria().getTargetPropertyName(); + + List> nameMatches = new ArrayList<>(); + List> scopeMatches = new ArrayList<>(); + List> nameAndScopeMatches = new ArrayList<>(); XmlElementRefInfo xmlElementRefInfo = - findXmlElementRef( mappingMethod.getResultType(), criteria.getTargetPropertyName() ); + findXmlElementRef( resultType, targetPropertyName ); for ( SelectedMethod candidate : methods ) { if ( !( candidate.getMethod() instanceof SourceMethod ) ) { @@ -75,14 +62,14 @@ public List> getMatchingMethods(Method mapp } SourceMethod candidateMethod = (SourceMethod) candidate.getMethod(); - XmlElementDeclPrism xmlElememtDecl = XmlElementDeclPrism.getInstanceOn( candidateMethod.getExecutable() ); + XmlElementDeclInfo xmlElementDeclInfo = getXmlElementDeclInfo( candidateMethod.getExecutable() ); - if ( xmlElememtDecl == null ) { + if ( xmlElementDeclInfo == null ) { continue; } - String name = xmlElememtDecl.name(); - TypeMirror scope = xmlElememtDecl.scope(); + String name = xmlElementDeclInfo.nameValue(); + TypeMirror scope = xmlElementDeclInfo.scopeType(); boolean nameIsSetAndMatches = name != null && name.equals( xmlElementRefInfo.nameValue() ); boolean scopeIsSetAndMatches = @@ -101,13 +88,13 @@ else if ( scopeIsSetAndMatches ) { } } - if ( nameAndScopeMatches.size() > 0 ) { + if ( !nameAndScopeMatches.isEmpty() ) { return nameAndScopeMatches; } - else if ( scopeMatches.size() > 0 ) { + else if ( !scopeMatches.isEmpty() ) { return scopeMatches; } - else if ( nameMatches.size() > 0 ) { + else if ( !nameMatches.isEmpty() ) { return nameMatches; } else { @@ -153,9 +140,9 @@ private XmlElementRefInfo findXmlElementRef(Type resultType, String targetProper for ( Element enclosed : currentElement.getEnclosedElements() ) { if ( enclosed.getKind().equals( ElementKind.FIELD ) && enclosed.getSimpleName().contentEquals( targetPropertyName ) ) { - XmlElementRefPrism xmlElementRef = XmlElementRefPrism.getInstanceOn( enclosed ); - if ( xmlElementRef != null ) { - return new XmlElementRefInfo( xmlElementRef.name(), currentMirror ); + XmlElementRefInfo xmlElementRefInfo = getXmlElementRefInfo( enclosed ); + if ( xmlElementRefInfo != null ) { + return new XmlElementRefInfo( xmlElementRefInfo.nameValue(), currentMirror ); } } } @@ -165,7 +152,11 @@ private XmlElementRefInfo findXmlElementRef(Type resultType, String targetProper return defaultInfo; } - private static class XmlElementRefInfo { + abstract XmlElementDeclInfo getXmlElementDeclInfo(Element element); + + abstract XmlElementRefInfo getXmlElementRefInfo(Element element); + + static class XmlElementRefInfo { private final String nameValue; private final TypeMirror sourceType; @@ -174,12 +165,37 @@ private static class XmlElementRefInfo { this.sourceType = sourceType; } - public String nameValue() { + String nameValue() { return nameValue; } - public TypeMirror sourceType() { + TypeMirror sourceType() { return sourceType; } } + + /** + * A class, whose purpose is to combine the use of + * {@link org.mapstruct.ap.internal.gem.XmlElementDeclGem} + * and + * {@link org.mapstruct.ap.internal.gem.jakarta.XmlElementDeclGem}. + */ + static class XmlElementDeclInfo { + + private final String nameValue; + private final TypeMirror scopeType; + + XmlElementDeclInfo(String nameValue, TypeMirror scopeType) { + this.nameValue = nameValue; + this.scopeType = scopeType; + } + + String nameValue() { + return nameValue; + } + + TypeMirror scopeType() { + return scopeType; + } + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/package-info.java index 7563231eaf..60bfa41d1e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/source/selector/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/option/MappingOption.java b/processor/src/main/java/org/mapstruct/ap/internal/option/MappingOption.java new file mode 100644 index 0000000000..4607fc1ecf --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/option/MappingOption.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.option; + +/** + * The different compiler mapping options that are available in MapStruct. + * + * @author Filip Hrisafov + */ +public enum MappingOption { + + // CHECKSTYLE:OFF + SUPPRESS_GENERATOR_TIMESTAMP( "mapstruct.suppressGeneratorTimestamp" ), + SUPPRESS_GENERATOR_VERSION_INFO_COMMENT( "mapstruct.suppressGeneratorVersionInfoComment" ), + UNMAPPED_TARGET_POLICY("mapstruct.unmappedTargetPolicy"), + UNMAPPED_SOURCE_POLICY("mapstruct.unmappedSourcePolicy"), + DEFAULT_COMPONENT_MODEL("mapstruct.defaultComponentModel"), + DEFAULT_INJECTION_STRATEGY("mapstruct.defaultInjectionStrategy"), + ALWAYS_GENERATE_SERVICE_FILE("mapstruct.alwaysGenerateServicesFile"), + DISABLE_BUILDERS("mapstruct.disableBuilders"), + VERBOSE("mapstruct.verbose"), + NULL_VALUE_ITERABLE_MAPPING_STRATEGY("mapstruct.nullValueIterableMappingStrategy"), + NULL_VALUE_MAP_MAPPING_STRATEGY("mapstruct.nullValueMapMappingStrategy"), + DISABLE_LIFECYCLE_OVERLOAD_DEDUPLICATE_SELECTOR("mapstruct.disableLifecycleOverloadDeduplicateSelector"), + DISABLE_JSPECIFY("mapstruct.disableJSpecify"), + ; + // CHECKSTYLE:ON + + private final String optionName; + + MappingOption(String optionName) { + this.optionName = optionName; + } + + /** + * Returns the name of the option, which can be used in the compiler arguments. + * + * @return the name of the option + */ + public String getOptionName() { + return optionName; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/option/Options.java b/processor/src/main/java/org/mapstruct/ap/internal/option/Options.java index 03adaa3544..1fd3585301 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/option/Options.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/option/Options.java @@ -1,65 +1,98 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.option; -import org.mapstruct.ap.internal.prism.ReportingPolicyPrism; +import java.util.Locale; +import java.util.Map; + +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; /** * The options passed to the code generator. * * @author Andreas Gudian * @author Gunnar Morling + * @author Filip Hrisafov */ public class Options { - private final boolean suppressGeneratorTimestamp; - private final boolean suppressGeneratorVersionComment; - private final ReportingPolicyPrism unmappedTargetPolicy; - private final boolean alwaysGenerateSpi; - private final String defaultComponentModel; - - public Options(boolean suppressGeneratorTimestamp, boolean suppressGeneratorVersionComment, - ReportingPolicyPrism unmappedTargetPolicy, - String defaultComponentModel, boolean alwaysGenerateSpi) { - this.suppressGeneratorTimestamp = suppressGeneratorTimestamp; - this.suppressGeneratorVersionComment = suppressGeneratorVersionComment; - this.unmappedTargetPolicy = unmappedTargetPolicy; - this.defaultComponentModel = defaultComponentModel; - this.alwaysGenerateSpi = alwaysGenerateSpi; + + private final Map options; + + public Options(Map options) { + this.options = options; } public boolean isSuppressGeneratorTimestamp() { - return suppressGeneratorTimestamp; + return parseBoolean( MappingOption.SUPPRESS_GENERATOR_TIMESTAMP ); } public boolean isSuppressGeneratorVersionComment() { - return suppressGeneratorVersionComment; + return parseBoolean( MappingOption.SUPPRESS_GENERATOR_VERSION_INFO_COMMENT ); } - public ReportingPolicyPrism getUnmappedTargetPolicy() { - return unmappedTargetPolicy; + public ReportingPolicyGem getUnmappedTargetPolicy() { + return parseEnum( MappingOption.UNMAPPED_TARGET_POLICY, ReportingPolicyGem.class ); + } + + public ReportingPolicyGem getUnmappedSourcePolicy() { + return parseEnum( MappingOption.UNMAPPED_SOURCE_POLICY, ReportingPolicyGem.class ); } public String getDefaultComponentModel() { - return defaultComponentModel; + return options.get( MappingOption.DEFAULT_COMPONENT_MODEL.getOptionName() ); + } + + public String getDefaultInjectionStrategy() { + return options.get( MappingOption.DEFAULT_INJECTION_STRATEGY.getOptionName() ); } public boolean isAlwaysGenerateSpi() { - return alwaysGenerateSpi; + return parseBoolean( MappingOption.ALWAYS_GENERATE_SERVICE_FILE ); + } + + public boolean isDisableBuilders() { + return parseBoolean( MappingOption.DISABLE_BUILDERS ); + } + + public boolean isVerbose() { + return parseBoolean( MappingOption.VERBOSE ); + } + + public NullValueMappingStrategyGem getNullValueIterableMappingStrategy() { + return parseEnum( MappingOption.NULL_VALUE_ITERABLE_MAPPING_STRATEGY, NullValueMappingStrategyGem.class ); + } + + public NullValueMappingStrategyGem getNullValueMapMappingStrategy() { + return parseEnum( MappingOption.NULL_VALUE_MAP_MAPPING_STRATEGY, NullValueMappingStrategyGem.class ); + } + + public boolean isDisableLifecycleOverloadDeduplicateSelector() { + return parseBoolean( MappingOption.DISABLE_LIFECYCLE_OVERLOAD_DEDUPLICATE_SELECTOR ); + } + + public boolean isDisableJSpecify() { + return parseBoolean( MappingOption.DISABLE_JSPECIFY ); + } + + private boolean parseBoolean(MappingOption option) { + if ( options.isEmpty() ) { + return false; + } + return Boolean.parseBoolean( options.get( option.getOptionName() ) ); + } + + private > E parseEnum(MappingOption option, Class enumType) { + if ( options.isEmpty() ) { + return null; + } + String value = options.get( option.getOptionName() ); + if ( value == null ) { + return null; + } + return Enum.valueOf( enumType, value.toUpperCase( Locale.ROOT ) ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/option/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/option/package-info.java index 0de96a97b6..87bb426eaf 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/option/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/option/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/CollectionMappingStrategyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/CollectionMappingStrategyPrism.java deleted file mode 100644 index a68fa477b5..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/CollectionMappingStrategyPrism.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - -/** - * Prism for the enum {@link org.mapstruct.CollectionMappingStrategy} - * - * @author Andreas Gudian - */ -public enum CollectionMappingStrategyPrism { - - ACCESSOR_ONLY, - SETTER_PREFERRED, - ADDER_PREFERRED, - TARGET_IMMUTABLE; -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/InjectionStrategyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/InjectionStrategyPrism.java deleted file mode 100644 index 18860bc37e..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/InjectionStrategyPrism.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - -/** - * Prism for the enum {@link org.mapstruct.InjectionStrategy}. - * - * @author Kevin Grüneberg - */ -public enum InjectionStrategyPrism { - - FIELD, - CONSTRUCTOR; -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingConstantsPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingConstantsPrism.java deleted file mode 100644 index bc2ccd7b03..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingConstantsPrism.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - -/** - * Prism for the enum {@link org.mapstruct.MappingConstants} - * - * @author Sjaak Derksen - */ -public final class MappingConstantsPrism { - - private MappingConstantsPrism() { - } - - public static final String NULL = ""; - - public static final String ANY_REMAINING = ""; - - public static final String ANY_UNMAPPED = ""; - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java deleted file mode 100644 index 5a18f80832..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/MappingInheritanceStrategyPrism.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - - -/** - * Prism for the enum {@link org.mapstruct.MappingInheritanceStrategy} - * - * @author Andreas Gudian - */ -public enum MappingInheritanceStrategyPrism { - - EXPLICIT( false, false, false ), - AUTO_INHERIT_FROM_CONFIG( true, true, false ), - AUTO_INHERIT_REVERSE_FROM_CONFIG( true, false, true ), - AUTO_INHERIT_ALL_FROM_CONFIG( true, true, true ); - - private final boolean autoInherit; - private final boolean applyForward; - private final boolean applyReverse; - - MappingInheritanceStrategyPrism(boolean isAutoInherit, boolean applyForward, boolean applyReverse) { - this.autoInherit = isAutoInherit; - this.applyForward = applyForward; - this.applyReverse = applyReverse; - } - - public boolean isAutoInherit() { - return autoInherit; - } - - public boolean isApplyForward() { - return applyForward; - } - - public boolean isApplyReverse() { - return applyReverse; - } - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategyPrism.java deleted file mode 100644 index f392c3415e..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueCheckStrategyPrism.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - - -/** - * Prism for the enum {@link org.mapstruct.SourceValuePresenceCheckStrategy} - * - * @author Sean Huang - */ -public enum NullValueCheckStrategyPrism { - - ON_IMPLICIT_CONVERSION, - ALWAYS; -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueMappingStrategyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueMappingStrategyPrism.java deleted file mode 100644 index d7e33ff8ef..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/NullValueMappingStrategyPrism.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - -/** - * Prism for the enum {@link org.mapstruct.NullValueMappingStrategy} - * - * @author Sjaak Derksen - */ -public enum NullValueMappingStrategyPrism { - - RETURN_NULL, - RETURN_DEFAULT; -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/PrismGenerator.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/PrismGenerator.java deleted file mode 100644 index 5b2a6fb7dc..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/PrismGenerator.java +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlElementRef; - -import org.mapstruct.AfterMapping; -import org.mapstruct.BeanMapping; -import org.mapstruct.BeforeMapping; -import org.mapstruct.Builder; -import org.mapstruct.Context; -import org.mapstruct.DecoratedWith; -import org.mapstruct.InheritConfiguration; -import org.mapstruct.InheritInverseConfiguration; -import org.mapstruct.IterableMapping; -import org.mapstruct.MapMapping; -import org.mapstruct.Mapper; -import org.mapstruct.MapperConfig; -import org.mapstruct.Mapping; -import org.mapstruct.MappingTarget; -import org.mapstruct.Mappings; -import org.mapstruct.Named; -import org.mapstruct.ObjectFactory; -import org.mapstruct.Qualifier; -import org.mapstruct.TargetType; -import org.mapstruct.ValueMapping; -import org.mapstruct.ValueMappings; - -import net.java.dev.hickory.prism.GeneratePrism; -import net.java.dev.hickory.prism.GeneratePrisms; - -/** - * Triggers the generation of prism types using Hickory. - * - * @author Gunnar Morling - */ -@GeneratePrisms({ - @GeneratePrism(value = Mapper.class, publicAccess = true), - @GeneratePrism(value = Mapping.class, publicAccess = true), - @GeneratePrism(value = Mappings.class, publicAccess = true), - @GeneratePrism(value = IterableMapping.class, publicAccess = true), - @GeneratePrism(value = BeanMapping.class, publicAccess = true), - @GeneratePrism(value = MapMapping.class, publicAccess = true), - @GeneratePrism(value = TargetType.class, publicAccess = true), - @GeneratePrism(value = MappingTarget.class, publicAccess = true), - @GeneratePrism(value = DecoratedWith.class, publicAccess = true), - @GeneratePrism(value = MapperConfig.class, publicAccess = true), - @GeneratePrism(value = InheritConfiguration.class, publicAccess = true), - @GeneratePrism(value = InheritInverseConfiguration.class, publicAccess = true), - @GeneratePrism(value = Qualifier.class, publicAccess = true), - @GeneratePrism(value = Named.class, publicAccess = true), - @GeneratePrism(value = ObjectFactory.class, publicAccess = true), - @GeneratePrism(value = AfterMapping.class, publicAccess = true), - @GeneratePrism(value = BeforeMapping.class, publicAccess = true), - @GeneratePrism(value = ValueMapping.class, publicAccess = true), - @GeneratePrism(value = ValueMappings.class, publicAccess = true), - @GeneratePrism(value = Context.class, publicAccess = true), - @GeneratePrism(value = Builder.class, publicAccess = true), - - // external types - @GeneratePrism(value = XmlElementDecl.class, publicAccess = true), - @GeneratePrism(value = XmlElementRef.class, publicAccess = true) -}) -public class PrismGenerator { - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/ReportingPolicyPrism.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/ReportingPolicyPrism.java deleted file mode 100644 index 9067ff0780..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/ReportingPolicyPrism.java +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.prism; - -import javax.tools.Diagnostic; -import javax.tools.Diagnostic.Kind; - -/** - * Prism for the enum {@link org.mapstruct.ReportingPolicy}. - * - * @author Gunnar Morling - */ -public enum ReportingPolicyPrism { - - IGNORE( null, false, false ), - WARN( Kind.WARNING, true, false ), - ERROR( Kind.ERROR, true, true ); - - private final Diagnostic.Kind diagnosticKind; - private final boolean requiresReport; - private final boolean failsBuild; - - ReportingPolicyPrism(Diagnostic.Kind diagnosticKind, boolean requiresReport, boolean failsBuild) { - this.requiresReport = requiresReport; - this.diagnosticKind = diagnosticKind; - this.failsBuild = failsBuild; - } - - public Diagnostic.Kind getDiagnosticKind() { - return diagnosticKind; - } - - public boolean requiresReport() { - return requiresReport; - } - - public boolean failsBuild() { - return failsBuild; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/prism/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/prism/package-info.java deleted file mode 100644 index 69aad2bb11..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/prism/package-info.java +++ /dev/null @@ -1,24 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/** - *

      - * This package contains the generated prism types for accessing the MapStruct annotations in a comfortable way. - *

      - */ -package org.mapstruct.ap.internal.prism; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java index 40ef3c9c5d..bbd695412a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/AnnotationBasedComponentModelProcessor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; @@ -24,10 +11,12 @@ import java.util.List; import java.util.ListIterator; import java.util.Set; - +import java.util.stream.Collectors; import javax.lang.model.element.TypeElement; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; import org.mapstruct.ap.internal.model.AnnotatedConstructor; +import org.mapstruct.ap.internal.model.AnnotatedSetter; import org.mapstruct.ap.internal.model.Annotation; import org.mapstruct.ap.internal.model.AnnotationMapperReference; import org.mapstruct.ap.internal.model.Decorator; @@ -36,8 +25,7 @@ import org.mapstruct.ap.internal.model.MapperReference; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.prism.InjectionStrategyPrism; -import org.mapstruct.ap.internal.util.MapperConfiguration; +import org.mapstruct.ap.internal.model.source.MapperOptions; /** * An {@link ModelElementProcessor} which converts the given {@link Mapper} object into an annotation based component @@ -55,10 +43,10 @@ public abstract class AnnotationBasedComponentModelProcessor implements ModelEle public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, Mapper mapper) { this.typeFactory = context.getTypeFactory(); - MapperConfiguration mapperConfiguration = MapperConfiguration.getInstanceOn( mapperTypeElement ); + MapperOptions mapperAnnotation = MapperOptions.getInstanceOn( mapperTypeElement, context.getOptions() ); - String componentModel = mapperConfiguration.componentModel( context.getOptions() ); - InjectionStrategyPrism injectionStrategy = mapperConfiguration.getInjectionStrategy(); + String componentModel = mapperAnnotation.componentModel(); + InjectionStrategyGem injectionStrategy = mapperAnnotation.getInjectionStrategy(); if ( !getComponentModelIdentifier().equalsIgnoreCase( componentModel ) ) { return mapper; @@ -76,32 +64,38 @@ else if ( mapper.getDecorator() != null ) { } List annotations = getMapperReferenceAnnotations(); - ListIterator iterator = mapper.getReferencedMappers().listIterator(); + ListIterator iterator = mapper.getFields().listIterator(); while ( iterator.hasNext() ) { - MapperReference reference = iterator.next(); - iterator.remove(); - iterator.add( replacementMapperReference( reference, annotations, injectionStrategy ) ); + + Field reference = iterator.next(); + if ( reference instanceof MapperReference ) { + iterator.remove(); + iterator.add( replacementMapperReference( reference, annotations, injectionStrategy ) ); + } } - if ( injectionStrategy == InjectionStrategyPrism.CONSTRUCTOR ) { + if ( injectionStrategy == InjectionStrategyGem.CONSTRUCTOR ) { buildConstructors( mapper ); } + else if ( injectionStrategy == InjectionStrategyGem.SETTER ) { + buildSetters( mapper ); + } return mapper; } - protected void adjustDecorator(Mapper mapper, InjectionStrategyPrism injectionStrategy) { + protected void adjustDecorator(Mapper mapper, InjectionStrategyGem injectionStrategy) { Decorator decorator = mapper.getDecorator(); - for ( Annotation typeAnnotation : getDecoratorAnnotations() ) { + for ( Annotation typeAnnotation : getDecoratorAnnotations( decorator ) ) { decorator.addAnnotation( typeAnnotation ); } decorator.removeConstructor(); List annotations = getDelegatorReferenceAnnotations( mapper ); - List replacement = new ArrayList(); + List replacement = new ArrayList<>(); if ( !decorator.getMethods().isEmpty() ) { for ( Field field : decorator.getFields() ) { replacement.add( replacementMapperReference( field, annotations, injectionStrategy ) ); @@ -110,8 +104,54 @@ protected void adjustDecorator(Mapper mapper, InjectionStrategyPrism injectionSt decorator.setFields( replacement ); } + private List toMapperReferences(List fields) { + List mapperReferences = new ArrayList<>(); + for ( Field field : fields ) { + if ( field instanceof MapperReference ) { + mapperReferences.add( (MapperReference) field ); + } + } + return mapperReferences; + } + + private void buildSetters(Mapper mapper) { + List mapperReferences = toMapperReferences( mapper.getFields() ); + for ( MapperReference mapperReference : mapperReferences ) { + if ( mapperReference.isUsed() ) { + AnnotatedSetter setter = new AnnotatedSetter( + mapperReference, + getMapperReferenceAnnotations(), + Collections.emptyList() + ); + mapper.getMethods().add( setter ); + } + } + + Decorator decorator = mapper.getDecorator(); + if ( decorator != null ) { + List mapperReferenceAnnotations = getMapperReferenceAnnotations(); + Set mapperReferenceAnnotationsTypes = mapperReferenceAnnotations + .stream() + .map( Annotation::getType ) + .collect( Collectors.toSet() ); + for ( Field field : decorator.getFields() ) { + if ( field instanceof AnnotationMapperReference ) { + + List fieldAnnotations = ( (AnnotationMapperReference) field ).getAnnotations(); + + List qualifiers = extractMissingAnnotations( + fieldAnnotations, + mapperReferenceAnnotationsTypes + ); + + decorator.getMethods().add( new AnnotatedSetter( field, mapperReferenceAnnotations, qualifiers ) ); + } + } + } + } + private void buildConstructors(Mapper mapper) { - if ( !mapper.getReferencedMappers().isEmpty() ) { + if ( !toMapperReferences( mapper.getFields() ).isEmpty() ) { AnnotatedConstructor annotatedConstructor = buildAnnotatedConstructorForMapper( mapper ); if ( !annotatedConstructor.getMapperReferences().isEmpty() ) { @@ -130,10 +170,11 @@ private void buildConstructors(Mapper mapper) { } private AnnotatedConstructor buildAnnotatedConstructorForMapper(Mapper mapper) { + List mapperReferences = toMapperReferences( mapper.getFields() ); List mapperReferencesForConstructor = - new ArrayList( mapper.getReferencedMappers().size() ); + new ArrayList<>( mapperReferences.size() ); - for ( MapperReference mapperReference : mapper.getReferencedMappers() ) { + for ( MapperReference mapperReference : mapperReferences ) { if ( mapperReference.isUsed() ) { mapperReferencesForConstructor.add( (AnnotationMapperReference) mapperReference ); } @@ -143,16 +184,18 @@ private AnnotatedConstructor buildAnnotatedConstructorForMapper(Mapper mapper) { removeDuplicateAnnotations( mapperReferencesForConstructor, mapperReferenceAnnotations ); - return new AnnotatedConstructor( + return AnnotatedConstructor.forComponentModels( mapper.getName(), mapperReferencesForConstructor, mapperReferenceAnnotations, - additionalPublicEmptyConstructor() ); + mapper.getConstructor(), + additionalPublicEmptyConstructor() + ); } private AnnotatedConstructor buildAnnotatedConstructorForDecorator(Decorator decorator) { List mapperReferencesForConstructor = - new ArrayList( decorator.getFields().size() ); + new ArrayList<>( decorator.getFields().size() ); for ( Field field : decorator.getFields() ) { if ( field instanceof AnnotationMapperReference ) { @@ -164,11 +207,13 @@ private AnnotatedConstructor buildAnnotatedConstructorForDecorator(Decorator dec removeDuplicateAnnotations( mapperReferencesForConstructor, mapperReferenceAnnotations ); - return new AnnotatedConstructor( + return AnnotatedConstructor.forComponentModels( decorator.getName(), mapperReferencesForConstructor, mapperReferenceAnnotations, - additionalPublicEmptyConstructor() ); + decorator.getConstructor(), + additionalPublicEmptyConstructor() + ); } /** @@ -183,7 +228,7 @@ private void removeDuplicateAnnotations(List annotati List mapperReferenceAnnotations) { ListIterator mapperReferenceIterator = annotationMapperReferences.listIterator(); - Set mapperReferenceAnnotationsTypes = new HashSet(); + Set mapperReferenceAnnotationsTypes = new HashSet<>(); for ( Annotation annotation : mapperReferenceAnnotations ) { mapperReferenceAnnotationsTypes.add( annotation.getType() ); } @@ -192,17 +237,33 @@ private void removeDuplicateAnnotations(List annotati AnnotationMapperReference annotationMapperReference = mapperReferenceIterator.next(); mapperReferenceIterator.remove(); - List qualifiers = new ArrayList(); - for ( Annotation annotation : annotationMapperReference.getAnnotations() ) { - if ( !mapperReferenceAnnotationsTypes.contains( annotation.getType() ) ) { - qualifiers.add( annotation ); - } - } + List qualifiers = extractMissingAnnotations( + annotationMapperReference.getAnnotations(), + mapperReferenceAnnotationsTypes + ); mapperReferenceIterator.add( annotationMapperReference.withNewAnnotations( qualifiers ) ); } } + /** + * Extract all annotations from {@code annotations} that do not have a type in {@code annotationTypes}. + * + * @param annotations the annotations from which we need to extract information + * @param annotationTypes the annotation types to ignore + * @return the annotations that are not in the {@code annotationTypes} + */ + private List extractMissingAnnotations(List annotations, + Set annotationTypes) { + List qualifiers = new ArrayList<>(); + for ( Annotation annotation : annotations ) { + if ( !annotationTypes.contains( annotation.getType() ) ) { + qualifiers.add( annotation ); + } + } + return qualifiers; + } + protected boolean additionalPublicEmptyConstructor() { return false; } @@ -214,15 +275,15 @@ protected List getDelegatorReferenceAnnotations(Mapper mapper) { /** * @param originalReference the reference to be replaced * @param annotations the list of annotations - * @param injectionStrategyPrism strategy for injection + * @param injectionStrategy strategy for injection * @return the mapper reference replacing the original one */ - protected MapperReference replacementMapperReference(Field originalReference, List annotations, - InjectionStrategyPrism injectionStrategyPrism) { + protected Field replacementMapperReference(Field originalReference, List annotations, + InjectionStrategyGem injectionStrategy) { boolean finalField = - injectionStrategyPrism == InjectionStrategyPrism.CONSTRUCTOR && !additionalPublicEmptyConstructor(); + injectionStrategy == InjectionStrategyGem.CONSTRUCTOR && !additionalPublicEmptyConstructor(); - boolean includeAnnotationsOnField = injectionStrategyPrism == InjectionStrategyPrism.FIELD; + boolean includeAnnotationsOnField = injectionStrategy == InjectionStrategyGem.FIELD; return new AnnotationMapperReference( originalReference.getType(), @@ -247,7 +308,7 @@ protected MapperReference replacementMapperReference(Field originalReference, Li /** * @return the annotation(s) to be added at the decorator of the mapper */ - protected List getDecoratorAnnotations() { + protected List getDecoratorAnnotations(Decorator decorator) { return Collections.emptyList(); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java index cb41987785..d8f136034b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/CdiComponentProcessor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; @@ -22,8 +9,11 @@ import java.util.Collections; import java.util.List; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; import org.mapstruct.ap.internal.model.Annotation; import org.mapstruct.ap.internal.model.Mapper; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.AnnotationProcessingException; /** * A {@link ModelElementProcessor} which converts the given {@link Mapper} @@ -36,19 +26,19 @@ public class CdiComponentProcessor extends AnnotationBasedComponentModelProcesso @Override protected String getComponentModelIdentifier() { - return "cdi"; + return MappingConstantsGem.ComponentModelGem.CDI; } @Override protected List getTypeAnnotations(Mapper mapper) { return Collections.singletonList( - new Annotation( getTypeFactory().getType( "javax.enterprise.context.ApplicationScoped" ) ) + new Annotation( getType( "ApplicationScoped" ) ) ); } @Override protected List getMapperReferenceAnnotations() { - return Arrays.asList( new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) ) ); + return Arrays.asList( new Annotation( getType( "Inject" ) ) ); } @Override @@ -60,4 +50,24 @@ protected boolean requiresGenerationOfDecoratorClass() { protected boolean additionalPublicEmptyConstructor() { return true; } + + private Type getType(String simpleName) { + String javaxPrefix = "javax.inject."; + String jakartaPrefix = "jakarta.inject."; + if ( "ApplicationScoped".equals( simpleName ) ) { + javaxPrefix = "javax.enterprise.context."; + jakartaPrefix = "jakarta.enterprise.context."; + } + if ( getTypeFactory().isTypeAvailable( javaxPrefix + simpleName ) ) { + return getTypeFactory().getType( javaxPrefix + simpleName ); + } + + if ( getTypeFactory().isTypeAvailable( jakartaPrefix + simpleName ) ) { + return getTypeFactory().getType( jakartaPrefix + simpleName ); + } + + throw new AnnotationProcessingException( + "Couldn't find any of the CDI or Jakarta CDI Dependency types." + + " Are you missing a dependency on your classpath?" ); + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java index 70ef02e45f..7a0596d4c2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultModelElementProcessorContext.java @@ -1,42 +1,34 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; +import java.util.Map; +import java.util.stream.IntStream; import javax.annotation.processing.Filer; import javax.annotation.processing.Messager; import javax.annotation.processing.ProcessingEnvironment; import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; +import javax.lang.model.element.TypeElement; import javax.tools.Diagnostic.Kind; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.processor.ModelElementProcessor.ProcessorContext; import org.mapstruct.ap.internal.util.AccessorNamingUtils; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.FormattingMessager; import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.NullabilityResolver; import org.mapstruct.ap.internal.util.RoundContext; -import org.mapstruct.ap.internal.util.workarounds.TypesDecorator; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.version.VersionInformation; +import org.mapstruct.ap.spi.EnumMappingStrategy; +import org.mapstruct.ap.spi.EnumTransformationStrategy; /** * Default implementation of the processor context. @@ -50,22 +42,31 @@ public class DefaultModelElementProcessorContext implements ProcessorContext { private final Options options; private final TypeFactory typeFactory; private final VersionInformation versionInformation; - private final Types delegatingTypes; + private final TypeUtils delegatingTypes; + private final ElementUtils delegatingElements; private final AccessorNamingUtils accessorNaming; + private final NullabilityResolver nullabilityResolver; + private final RoundContext roundContext; public DefaultModelElementProcessorContext(ProcessingEnvironment processingEnvironment, Options options, - RoundContext roundContext) { + RoundContext roundContext, Map notToBeImported, TypeElement mapperElement) { this.processingEnvironment = processingEnvironment; - this.messager = new DelegatingMessager( processingEnvironment.getMessager() ); + this.messager = new DelegatingMessager( processingEnvironment.getMessager(), options.isVerbose() ); this.accessorNaming = roundContext.getAnnotationProcessorContext().getAccessorNaming(); + this.nullabilityResolver = roundContext.getAnnotationProcessorContext().getNullabilityResolver(); this.versionInformation = DefaultVersionInformation.fromProcessingEnvironment( processingEnvironment ); - this.delegatingTypes = new TypesDecorator( processingEnvironment, versionInformation ); + this.delegatingTypes = TypeUtils.create( processingEnvironment, versionInformation ); + this.delegatingElements = ElementUtils.create( processingEnvironment, versionInformation, mapperElement ); + this.roundContext = roundContext; this.typeFactory = new TypeFactory( - processingEnvironment.getElementUtils(), + delegatingElements, delegatingTypes, messager, - roundContext + roundContext, + notToBeImported, + options.isVerbose(), + versionInformation ); this.options = options; } @@ -76,13 +77,13 @@ public Filer getFiler() { } @Override - public Types getTypeUtils() { + public TypeUtils getTypeUtils() { return delegatingTypes; } @Override - public Elements getElementUtils() { - return processingEnvironment.getElementUtils(); + public ElementUtils getElementUtils() { + return delegatingElements; } @Override @@ -100,6 +101,21 @@ public AccessorNamingUtils getAccessorNaming() { return accessorNaming; } + @Override + public NullabilityResolver getNullabilityResolver() { + return nullabilityResolver; + } + + @Override + public Map getEnumTransformationStrategies() { + return roundContext.getAnnotationProcessorContext().getEnumTransformationStrategies(); + } + + @Override + public EnumMappingStrategy getEnumMappingStrategy() { + return roundContext.getAnnotationProcessorContext().getEnumMappingStrategy(); + } + @Override public Options getOptions() { return options; @@ -119,9 +135,11 @@ private static final class DelegatingMessager implements FormattingMessager { private final Messager delegate; private boolean isErroneous = false; + private final boolean verbose; - DelegatingMessager(Messager delegate) { + DelegatingMessager(Messager delegate, boolean verbose) { this.delegate = delegate; + this.verbose = verbose; } @Override @@ -144,10 +162,15 @@ public void printMessage(Element e, Message msg, Object... args) { @Override public void printMessage(Element e, AnnotationMirror a, Message msg, Object... args) { - String message = String.format( msg.getDescription(), args ); - delegate.printMessage( msg.getDiagnosticKind(), message, e, a ); - if ( msg.getDiagnosticKind() == Kind.ERROR ) { - isErroneous = true; + if ( a == null ) { + printMessage( e, msg, args ); + } + else { + String message = String.format( msg.getDescription(), args ); + delegate.printMessage( msg.getDiagnosticKind(), message, e, a ); + if ( msg.getDiagnosticKind() == Kind.ERROR ) { + isErroneous = true; + } } } @@ -161,6 +184,16 @@ public void printMessage(Element e, AnnotationMirror a, AnnotationValue v, Messa } } + public void note( int level, Message msg, Object... args ) { + if ( verbose ) { + StringBuilder builder = new StringBuilder(); + IntStream.range( 0, level ).mapToObj( i -> "-" ).forEach( builder::append ); + builder.append( " MapStruct: " ).append( String.format( msg.getDescription(), args ) ); + delegate.printMessage( Kind.NOTE, builder.toString() ); + } + } + + @Override public boolean isErroneous() { return isErroneous; } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultVersionInformation.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultVersionInformation.java index 8a1cd33513..f8053c92ab 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultVersionInformation.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/DefaultVersionInformation.java @@ -1,29 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; import java.io.IOException; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; import java.net.MalformedURLException; import java.net.URL; import java.util.jar.Manifest; - import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.SourceVersion; import org.mapstruct.ap.internal.version.VersionInformation; @@ -50,15 +39,25 @@ public class DefaultVersionInformation implements VersionInformation { private final String runtimeVersion; private final String runtimeVendor; private final String compiler; + private final boolean sourceVersionAtLeast9; + private final boolean sourceVersionAtLeast11; + private final boolean sourceVersionAtLeast14; + private final boolean sourceVersionAtLeast19; private final boolean eclipseJDT; private final boolean javac; - DefaultVersionInformation(String runtimeVersion, String runtimeVendor, String compiler) { + DefaultVersionInformation(String runtimeVersion, String runtimeVendor, String compiler, + SourceVersion sourceVersion) { this.runtimeVersion = runtimeVersion; this.runtimeVendor = runtimeVendor; this.compiler = compiler; this.eclipseJDT = compiler.startsWith( COMPILER_NAME_ECLIPSE_JDT ); this.javac = compiler.startsWith( COMPILER_NAME_JAVAC ); + // If the difference between the source version and RELEASE_6 is more that 2 than we are at least on 9 + this.sourceVersionAtLeast9 = sourceVersion.compareTo( SourceVersion.RELEASE_6 ) > 2; + this.sourceVersionAtLeast11 = sourceVersion.compareTo( SourceVersion.RELEASE_6 ) > 4; + this.sourceVersionAtLeast14 = sourceVersion.compareTo( SourceVersion.RELEASE_6 ) > 7; + this.sourceVersionAtLeast19 = sourceVersion.compareTo( SourceVersion.RELEASE_6 ) > 12; } @Override @@ -81,6 +80,26 @@ public String getCompiler() { return this.compiler; } + @Override + public boolean isSourceVersionAtLeast9() { + return sourceVersionAtLeast9; + } + + @Override + public boolean isSourceVersionAtLeast11() { + return sourceVersionAtLeast11; + } + + @Override + public boolean isSourceVersionAtLeast14() { + return sourceVersionAtLeast14; + } + + @Override + public boolean isSourceVersionAtLeast19() { + return sourceVersionAtLeast19; + } + @Override public boolean isEclipseJDTCompiler() { return eclipseJDT; @@ -97,11 +116,37 @@ static DefaultVersionInformation fromProcessingEnvironment(ProcessingEnvironment String compiler = getCompiler( processingEnv ); - return new DefaultVersionInformation( runtimeVersion, runtimeVendor, compiler ); + return new DefaultVersionInformation( + runtimeVersion, + runtimeVendor, + compiler, + processingEnv.getSourceVersion() + ); } private static String getCompiler(ProcessingEnvironment processingEnv) { - String className = processingEnv.getClass().getName(); + String className; + if ( Proxy.isProxyClass( processingEnv.getClass() ) ) { + // IntelliJ IDEA wraps the ProcessingEnvironment in a Proxy. + // Therefore we need smarter logic to determine the type of the compiler + String processingEnvToString = processingEnv.toString(); + if ( processingEnvToString.contains( COMPILER_NAME_JAVAC ) ) { + // The toString of the javac ProcessingEnvironment is "javac ProcessingEnvironment" + className = JAVAC_PE_CLASS; + } + else if ( processingEnvToString.startsWith( JDT_BATCH_PE_CLASS ) ) { + // The toString of the JDT Batch is from Object#toString so it contains the class name + className = JDT_BATCH_PE_CLASS; + } + else { + InvocationHandler invocationHandler = Proxy.getInvocationHandler( processingEnv ); + return "Proxy handler " + invocationHandler.getClass() + " from " + + getLibraryName( invocationHandler.getClass(), false ); + } + } + else { + className = processingEnv.getClass().getName(); + } if ( className.equals( JAVAC_PE_CLASS ) ) { return COMPILER_NAME_JAVAC; @@ -133,7 +178,10 @@ private static String getLibraryName(Class clazz, boolean preferVersionOnly) } } - if ( "jar".equals( resource.getProtocol() ) ) { + if ( resource == null ) { + return ""; + } + else if ( "jar".equals( resource.getProtocol() ) ) { return extractJarFileName( resource.getFile() ); } else if ( "jrt".equals( resource.getProtocol() ) ) { @@ -147,6 +195,9 @@ else if ( "bundleresource".equals( resource.getProtocol() ) && manifest != null } private static Manifest openManifest(String classFileName, URL resource) { + if ( resource == null ) { + return null; + } try { URL manifestUrl = createManifestUrl( classFileName, resource ); return new Manifest( manifestUrl.openStream() ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/JakartaCdiComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/JakartaCdiComponentProcessor.java new file mode 100644 index 0000000000..11c765668e --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/JakartaCdiComponentProcessor.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.processor; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.mapstruct.ap.internal.gem.MappingConstantsGem; +import org.mapstruct.ap.internal.model.Annotation; +import org.mapstruct.ap.internal.model.Mapper; + +/** + * A {@link ModelElementProcessor} which converts the given {@link Mapper} + * object into an application-scoped Jakarta CDI bean in case Jakarta CDI + * is configured as the target component model for this mapper. + * + * @author Filip Hrisafov + */ +public class JakartaCdiComponentProcessor extends AnnotationBasedComponentModelProcessor { + + @Override + protected String getComponentModelIdentifier() { + return MappingConstantsGem.ComponentModelGem.JAKARTA_CDI; + } + + @Override + protected List getTypeAnnotations(Mapper mapper) { + return Collections.singletonList( + new Annotation( getTypeFactory().getType( "jakarta.enterprise.context.ApplicationScoped" ) ) + ); + } + + @Override + protected List getMapperReferenceAnnotations() { + return Arrays.asList( new Annotation( getTypeFactory().getType( "jakarta.inject.Inject" ) ) ); + } + + @Override + protected boolean requiresGenerationOfDecoratorClass() { + return false; + } + + @Override + protected boolean additionalPublicEmptyConstructor() { + return true; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/JakartaComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/JakartaComponentProcessor.java new file mode 100644 index 0000000000..86c95d612b --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/JakartaComponentProcessor.java @@ -0,0 +1,84 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.processor; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.mapstruct.ap.internal.gem.MappingConstantsGem; +import org.mapstruct.ap.internal.model.Annotation; +import org.mapstruct.ap.internal.model.Decorator; +import org.mapstruct.ap.internal.model.Mapper; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement.AnnotationElementType; + +/** + * A {@link ModelElementProcessor} which converts the given {@link Mapper} + * object into a Jakarta Inject style bean in case "jakarta" is configured as the + * target component model for this mapper. + * + * @author Filip Hrisafov + */ +public class JakartaComponentProcessor extends AnnotationBasedComponentModelProcessor { + @Override + protected String getComponentModelIdentifier() { + return MappingConstantsGem.ComponentModelGem.JAKARTA; + } + + @Override + protected List getTypeAnnotations(Mapper mapper) { + if ( mapper.getDecorator() == null ) { + return Arrays.asList( singleton(), named() ); + } + else { + return Arrays.asList( singleton(), namedDelegate( mapper ) ); + } + } + + @Override + protected List getDecoratorAnnotations(Decorator decorator) { + return Arrays.asList( singleton(), named() ); + } + + @Override + protected List getDelegatorReferenceAnnotations(Mapper mapper) { + return Arrays.asList( inject(), namedDelegate( mapper ) ); + } + + @Override + protected List getMapperReferenceAnnotations() { + return Collections.singletonList( inject() ); + } + + @Override + protected boolean requiresGenerationOfDecoratorClass() { + return true; + } + + private Annotation singleton() { + return new Annotation( getTypeFactory().getType( "jakarta.inject.Singleton" ) ); + } + + private Annotation named() { + return new Annotation( getTypeFactory().getType( "jakarta.inject.Named" ) ); + } + + private Annotation namedDelegate(Mapper mapper) { + return new Annotation( + getTypeFactory().getType( "jakarta.inject.Named" ), + Collections.singletonList( + new AnnotationElement( AnnotationElementType.STRING, + Collections.singletonList( mapper.getPackageName() + "." + mapper.getName() ) + ) ) + ); + } + + private Annotation inject() { + return new Annotation( getTypeFactory().getType( "jakarta.inject.Inject" ) ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java index 7f6623ef52..7770eff16c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/Jsr330ComponentProcessor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; @@ -22,8 +9,14 @@ import java.util.Collections; import java.util.List; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; import org.mapstruct.ap.internal.model.Annotation; +import org.mapstruct.ap.internal.model.Decorator; import org.mapstruct.ap.internal.model.Mapper; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement.AnnotationElementType; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.util.AnnotationProcessingException; /** * A {@link ModelElementProcessor} which converts the given {@link Mapper} @@ -36,7 +29,7 @@ public class Jsr330ComponentProcessor extends AnnotationBasedComponentModelProcessor { @Override protected String getComponentModelIdentifier() { - return "jsr330"; + return MappingConstantsGem.ComponentModelGem.JSR330; } @Override @@ -50,7 +43,7 @@ protected List getTypeAnnotations(Mapper mapper) { } @Override - protected List getDecoratorAnnotations() { + protected List getDecoratorAnnotations(Decorator decorator) { return Arrays.asList( singleton(), named() ); } @@ -70,21 +63,39 @@ protected boolean requiresGenerationOfDecoratorClass() { } private Annotation singleton() { - return new Annotation( getTypeFactory().getType( "javax.inject.Singleton" ) ); + return new Annotation( getType( "Singleton" ) ); } private Annotation named() { - return new Annotation( getTypeFactory().getType( "javax.inject.Named" ) ); + return new Annotation( getType( "Named" ) ); } private Annotation namedDelegate(Mapper mapper) { return new Annotation( - getTypeFactory().getType( "javax.inject.Named" ), - Collections.singletonList( '"' + mapper.getPackageName() + "." + mapper.getName() + '"' ) + getType( "Named" ), + Collections.singletonList( + new AnnotationElement( + AnnotationElementType.STRING, + Collections.singletonList( mapper.getPackageName() + "." + mapper.getName() ) + ) ) ); } private Annotation inject() { - return new Annotation( getTypeFactory().getType( "javax.inject.Inject" ) ); + return new Annotation( getType( "Inject" ) ); + } + + private Type getType(String simpleName) { + if ( getTypeFactory().isTypeAvailable( "javax.inject." + simpleName ) ) { + return getTypeFactory().getType( "javax.inject." + simpleName ); + } + + if ( getTypeFactory().isTypeAvailable( "jakarta.inject." + simpleName ) ) { + return getTypeFactory().getType( "jakarta.inject." + simpleName ); + } + + throw new AnnotationProcessingException( + "Couldn't find any of the JSR330 or Jakarta Dependency Inject types." + + " Are you missing a dependency on your classpath?" ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperAnnotatedFormattingMessenger.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperAnnotatedFormattingMessenger.java new file mode 100644 index 0000000000..d3384f0b4c --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperAnnotatedFormattingMessenger.java @@ -0,0 +1,143 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.processor; + +import java.util.Objects; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic.Kind; + +import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.TypeUtils; + +/** + * Handles redirection of errors/warnings so that they're shown on the mapper instead of hidden on a superclass. + * + * @author Ben Zegveld + */ +public class MapperAnnotatedFormattingMessenger implements FormattingMessager { + + private FormattingMessager delegateMessager; + private TypeElement mapperTypeElement; + private TypeUtils typeUtils; + + public MapperAnnotatedFormattingMessenger(FormattingMessager delegateMessager, TypeElement mapperTypeElement, + TypeUtils typeUtils) { + this.delegateMessager = delegateMessager; + this.mapperTypeElement = mapperTypeElement; + this.typeUtils = typeUtils; + } + + @Override + public void printMessage(Message msg, Object... args) { + delegateMessager.printMessage( msg, args ); + } + + @Override + public void printMessage(Element e, Message msg, Object... args) { + delegateMessager + .printMessage( + determineDelegationElement( e ), + determineDelegationMessage( e, msg ), + determineDelegationArguments( e, msg, args ) ); + } + + @Override + public void printMessage(Element e, AnnotationMirror a, Message msg, Object... args) { + delegateMessager + .printMessage( + determineDelegationElement( e ), + a, + determineDelegationMessage( e, msg ), + determineDelegationArguments( e, msg, args ) ); + } + + @Override + public void printMessage(Element e, AnnotationMirror a, AnnotationValue v, Message msg, Object... args) { + delegateMessager + .printMessage( + determineDelegationElement( e ), + a, + v, + determineDelegationMessage( e, msg ), + determineDelegationArguments( e, msg, args ) ); + } + + @Override + public void note(int level, Message log, Object... args) { + delegateMessager.note( level, log, args ); + } + + @Override + public boolean isErroneous() { + return delegateMessager.isErroneous(); + } + + private Object[] determineDelegationArguments(Element e, Message msg, Object[] args) { + if ( methodInMapperClass( e ) ) { + return args; + } + String originalMessage = String.format( msg.getDescription(), args ); + return new Object[] { originalMessage, constructMethod( e ), e.getEnclosingElement().getSimpleName() }; + } + + /** + * ExecutableElement.toString() has different values depending on the compiler. Constructing the method itself + * manually will ensure that the message is always traceable to it's source. + */ + private String constructMethod(Element e) { + if ( e instanceof ExecutableElement ) { + ExecutableElement ee = (ExecutableElement) e; + StringBuilder method = new StringBuilder(); + method.append( typeMirrorToString( ee.getReturnType() ) ); + method.append( " " ); + method.append( ee.getSimpleName() ); + method.append( "(" ); + method.append( ee.getParameters() + .stream() + .map( this::parameterToString ) + .collect( Collectors.joining( ", " ) ) ); + method.append( ")" ); + return method.toString(); + } + return e.toString(); + } + + private String parameterToString(VariableElement element) { + return typeMirrorToString( element.asType() ) + " " + element.getSimpleName(); + } + + private String typeMirrorToString(TypeMirror type) { + Element element = typeUtils.asElement( type ); + return element != null ? element.getSimpleName().toString() : Objects.toString( type ); + } + + private Message determineDelegationMessage(Element e, Message msg) { + if ( methodInMapperClass( e ) ) { + return msg; + } + if ( msg.getDiagnosticKind() == Kind.ERROR ) { + return Message.MESSAGE_MOVED_TO_MAPPER_ERROR; + } + return Message.MESSAGE_MOVED_TO_MAPPER_WARNING; + } + + private Element determineDelegationElement(Element e) { + return methodInMapperClass( e ) ? e : mapperTypeElement; + } + + private boolean methodInMapperClass(Element e) { + return mapperTypeElement == null || e.equals( mapperTypeElement ) + || e.getEnclosingElement().equals( mapperTypeElement ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java index 37a3cd2775..db16d52106 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperCreationProcessor.java @@ -1,74 +1,78 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.gem.DecoratedWithGem; +import org.mapstruct.ap.internal.gem.InheritConfigurationGem; +import org.mapstruct.ap.internal.gem.InheritInverseConfigurationGem; +import org.mapstruct.ap.internal.gem.JavadocGem; +import org.mapstruct.ap.internal.gem.MapperGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.model.AdditionalAnnotationsBuilder; +import org.mapstruct.ap.internal.model.Annotation; import org.mapstruct.ap.internal.model.BeanMappingMethod; import org.mapstruct.ap.internal.model.ContainerMappingMethod; import org.mapstruct.ap.internal.model.ContainerMappingMethodBuilder; import org.mapstruct.ap.internal.model.Decorator; import org.mapstruct.ap.internal.model.DefaultMapperReference; import org.mapstruct.ap.internal.model.DelegatingMethod; -import org.mapstruct.ap.internal.model.EnumMappingMethod; +import org.mapstruct.ap.internal.model.Field; import org.mapstruct.ap.internal.model.IterableMappingMethod; +import org.mapstruct.ap.internal.model.Javadoc; import org.mapstruct.ap.internal.model.MapMappingMethod; import org.mapstruct.ap.internal.model.Mapper; import org.mapstruct.ap.internal.model.MapperReference; import org.mapstruct.ap.internal.model.MappingBuilderContext; import org.mapstruct.ap.internal.model.MappingMethod; import org.mapstruct.ap.internal.model.StreamMappingMethod; +import org.mapstruct.ap.internal.model.SupportingConstructorFragment; import org.mapstruct.ap.internal.model.ValueMappingMethod; +import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.model.common.FormattingParameters; -import org.mapstruct.ap.internal.model.source.MappingOptions; +import org.mapstruct.ap.internal.model.source.MapperOptions; +import org.mapstruct.ap.internal.model.source.MappingMethodOptions; import org.mapstruct.ap.internal.model.source.Method; import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.model.source.SourceMethod; import org.mapstruct.ap.internal.option.Options; -import org.mapstruct.ap.internal.prism.DecoratedWithPrism; -import org.mapstruct.ap.internal.prism.InheritConfigurationPrism; -import org.mapstruct.ap.internal.prism.InheritInverseConfigurationPrism; -import org.mapstruct.ap.internal.prism.MapperPrism; -import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; import org.mapstruct.ap.internal.processor.creation.MappingResolverImpl; import org.mapstruct.ap.internal.util.AccessorNamingUtils; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.MapperConfiguration; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.version.VersionInformation; +import static javax.lang.model.element.Modifier.FINAL; +import static javax.lang.model.element.Modifier.PUBLIC; +import static javax.lang.model.element.Modifier.STATIC; +import static org.mapstruct.ap.internal.model.SupportingConstructorFragment.addAllFragmentsIn; +import static org.mapstruct.ap.internal.model.SupportingField.addAllFieldsIn; import static org.mapstruct.ap.internal.util.Collections.first; import static org.mapstruct.ap.internal.util.Collections.join; @@ -80,8 +84,11 @@ */ public class MapperCreationProcessor implements ModelElementProcessor, Mapper> { - private Elements elementUtils; - private Types typeUtils; + /** Modifiers for public "constant" e.g. "public static final" */ + private static final List PUBLIC_CONSTANT_MODIFIERS = Arrays.asList( PUBLIC, STATIC, FINAL ); + + private ElementUtils elementUtils; + private TypeUtils typeUtils; private FormattingMessager messager; private Options options; private VersionInformation versionInformation; @@ -89,33 +96,43 @@ public class MapperCreationProcessor implements ModelElementProcessor sourceModel) { this.elementUtils = context.getElementUtils(); this.typeUtils = context.getTypeUtils(); - this.messager = context.getMessager(); + this.messager = + new MapperAnnotatedFormattingMessenger( context.getMessager(), mapperTypeElement, context.getTypeUtils() ); this.options = context.getOptions(); this.versionInformation = context.getVersionInformation(); this.typeFactory = context.getTypeFactory(); this.accessorNaming = context.getAccessorNaming(); + additionalAnnotationsBuilder = + new AdditionalAnnotationsBuilder( elementUtils, typeFactory, messager ); - MapperConfiguration mapperConfig = MapperConfiguration.getInstanceOn( mapperTypeElement ); - List mapperReferences = initReferencedMappers( mapperTypeElement, mapperConfig ); + MapperOptions mapperOptions = MapperOptions.getInstanceOn( mapperTypeElement, context.getOptions() ); + List mapperReferences = initReferencedMappers( mapperTypeElement, mapperOptions ); MappingBuilderContext ctx = new MappingBuilderContext( typeFactory, elementUtils, typeUtils, messager, + versionInformation, accessorNaming, + context.getNullabilityResolver(), + context.getEnumMappingStrategy(), + context.getEnumTransformationStrategies(), options, new MappingResolverImpl( messager, elementUtils, typeUtils, typeFactory, - new ArrayList( sourceModel ), - mapperReferences + new ArrayList<>( sourceModel ), + mapperReferences, + options.isVerbose() ), mapperTypeElement, //sourceModel is passed only to fetch the after/before mapping methods in lifecycleCallbackFactory; @@ -124,7 +141,7 @@ public Mapper process(ProcessorContext context, TypeElement mapperTypeElement, L mapperReferences ); this.mappingContext = ctx; - return getMapper( mapperTypeElement, mapperConfig, sourceModel ); + return getMapper( mapperTypeElement, mapperOptions, sourceModel ); } @Override @@ -132,14 +149,15 @@ public int getPriority() { return 1000; } - private List initReferencedMappers(TypeElement element, MapperConfiguration mapperConfig) { - List result = new LinkedList(); - List variableNames = new LinkedList(); + private List initReferencedMappers(TypeElement element, MapperOptions mapperAnnotation) { + List result = new LinkedList<>(); + List variableNames = new LinkedList<>(); - for ( TypeMirror usedMapper : mapperConfig.uses() ) { + for ( TypeMirror usedMapper : mapperAnnotation.uses() ) { DefaultMapperReference mapperReference = DefaultMapperReference.getInstance( typeFactory.getType( usedMapper ), - MapperPrism.getInstanceOn( typeUtils.asElement( usedMapper ) ) != null, + MapperGem.instanceOn( typeUtils.asElement( usedMapper ) ) != null, + hasSingletonInstance( usedMapper ), typeFactory, variableNames ); @@ -151,25 +169,55 @@ private List initReferencedMappers(TypeElement element, MapperC return result; } - private Mapper getMapper(TypeElement element, MapperConfiguration mapperConfig, List methods) { - List mapperReferences = mappingContext.getMapperReferences(); - List mappingMethods = getMappingMethods( mapperConfig, methods ); - mappingMethods.addAll( mappingContext.getUsedVirtualMappings() ); + private boolean hasSingletonInstance(TypeMirror mapper) { + return typeUtils.asElement( mapper ).getEnclosedElements().stream() + .anyMatch( a -> isPublicConstantOfType( a, "INSTANCE", mapper ) ); + } + + /** + * @return true if the element is a "public static final" field (e.g. a constant) + * named fieldName of type "fieldType" + */ + private boolean isPublicConstantOfType(Element element, String fieldName, TypeMirror fieldType) { + return element.getKind().isField() && + element.getModifiers().containsAll( PUBLIC_CONSTANT_MODIFIERS ) && + element.getSimpleName().contentEquals( fieldName ) && + typeUtils.isSameType( element.asType(), fieldType ); + } + + private Mapper getMapper(TypeElement element, MapperOptions mapperOptions, List methods) { + + List mappingMethods = getMappingMethods( mapperOptions, methods ); + mappingMethods.addAll( mappingContext.getUsedSupportedMappings() ); mappingMethods.addAll( mappingContext.getMappingsToGenerate() ); + // handle fields + List fields = new ArrayList<>( mappingContext.getMapperReferences() ); + Set supportingFieldSet = new LinkedHashSet<>(mappingContext.getUsedSupportedFields()); + addAllFieldsIn( mappingContext.getUsedSupportedMappings(), supportingFieldSet ); + fields.addAll( supportingFieldSet ); + + // handle constructor fragments + Set constructorFragments = new LinkedHashSet<>(); + addAllFragmentsIn( mappingContext.getUsedSupportedMappings(), constructorFragments ); + Mapper mapper = new Mapper.Builder() .element( element ) - .mappingMethods( mappingMethods ) - .mapperReferences( mapperReferences ) + .methods( mappingMethods ) + .fields( fields ) + .constructorFragments( constructorFragments ) .options( options ) .versionInformation( versionInformation ) - .decorator( getDecorator( element, methods, mapperConfig.implementationName(), - mapperConfig.implementationPackage() ) ) + .decorator( getDecorator( element, methods, mapperOptions ) ) .typeFactory( typeFactory ) .elementUtils( elementUtils ) - .extraImports( getExtraImports( element ) ) - .implName( mapperConfig.implementationName() ) - .implPackage( mapperConfig.implementationPackage() ) + .extraImports( getExtraImports( element, mapperOptions ) ) + .implName( mapperOptions.implementationName() ) + .implPackage( mapperOptions.implementationPackage() ) + .suppressGeneratorTimestamp( mapperOptions.suppressTimestampInGenerated() ) + .additionalAnnotations( additionalAnnotationsBuilder.getProcessedAnnotations( element ) ) + .javadoc( getJavadoc( element ) ) + .classAccessibility( mapperOptions.accessibility() ) .build(); if ( !mappingContext.getForgedMethodsUnderCreation().isEmpty() ) { @@ -177,24 +225,34 @@ private Mapper getMapper(TypeElement element, MapperConfiguration mapperConfig, mappingContext.getForgedMethodsUnderCreation().keySet() ); } + if ( element.getModifiers().contains( Modifier.PRIVATE ) ) { + // If the mapper element is private then we should report an error + // we can't generate an implementation for a private mapper + mappingContext.getMessager() + .printMessage( element, + Message.GENERAL_CANNOT_IMPLEMENT_PRIVATE_MAPPER, + element.getSimpleName().toString(), + element.getKind() == ElementKind.INTERFACE ? "interface" : "class" + ); + } + return mapper; } - private Decorator getDecorator(TypeElement element, List methods, String implName, - String implPackage) { - DecoratedWithPrism decoratorPrism = DecoratedWithPrism.getInstanceOn( element ); + private Decorator getDecorator(TypeElement element, List methods, MapperOptions mapperOptions) { + DecoratedWithGem decoratedWith = DecoratedWithGem.instanceOn( element ); - if ( decoratorPrism == null ) { + if ( decoratedWith == null ) { return null; } - TypeElement decoratorElement = (TypeElement) typeUtils.asElement( decoratorPrism.value() ); + TypeElement decoratorElement = (TypeElement) typeUtils.asElement( decoratedWith.value().get() ); if ( !typeUtils.isAssignable( decoratorElement.asType(), element.asType() ) ) { - messager.printMessage( element, decoratorPrism.mirror, Message.DECORATOR_NO_SUBTYPE ); + messager.printMessage( element, decoratedWith.mirror(), Message.DECORATOR_NO_SUBTYPE ); } - List mappingMethods = new ArrayList( methods.size() ); + List mappingMethods = new ArrayList<>( methods.size() ); for ( SourceMethod mappingMethod : methods ) { boolean implementationRequired = true; @@ -229,59 +287,66 @@ else if ( constructor.getParameters().size() == 1 ) { } if ( !hasDelegateConstructor && !hasDefaultConstructor ) { - messager.printMessage( element, decoratorPrism.mirror, Message.DECORATOR_CONSTRUCTOR ); + messager.printMessage( element, decoratedWith.mirror(), Message.DECORATOR_CONSTRUCTOR ); } + // Get annotations from the decorator class + Set decoratorAnnotations = additionalAnnotationsBuilder.getProcessedAnnotations( decoratorElement ); + Decorator decorator = new Decorator.Builder() .elementUtils( elementUtils ) .typeFactory( typeFactory ) .mapperElement( element ) - .decoratorPrism( decoratorPrism ) + .decoratedWith( decoratedWith ) .methods( mappingMethods ) .hasDelegateConstructor( hasDelegateConstructor ) .options( options ) .versionInformation( versionInformation ) - .implName( implName ) - .implPackage( implPackage ) - .extraImports( getExtraImports( element ) ) + .implName( mapperOptions.implementationName() ) + .implPackage( mapperOptions.implementationPackage() ) + .extraImports( getExtraImports( element, mapperOptions ) ) + .suppressGeneratorTimestamp( mapperOptions.suppressTimestampInGenerated() ) + .additionalAnnotations( decoratorAnnotations ) .build(); return decorator; } - private SortedSet getExtraImports(TypeElement element) { - SortedSet extraImports = new TreeSet(); + private SortedSet getExtraImports(TypeElement element, MapperOptions mapperOptions) { + SortedSet extraImports = new TreeSet<>(); - MapperConfiguration mapperConfiguration = MapperConfiguration.getInstanceOn( element ); - for ( TypeMirror extraImport : mapperConfiguration.imports() ) { - Type type = typeFactory.getType( extraImport ); + for ( TypeMirror extraImport : mapperOptions.imports() ) { + Type type = typeFactory.getAlwaysImportedType( extraImport ); extraImports.add( type ); } // Add original package if a dest package has been set - if ( !"default".equals( mapperConfiguration.implementationPackage() ) ) { + if ( !"default".equals( mapperOptions.implementationPackage() ) ) { extraImports.add( typeFactory.getType( element ) ); } return extraImports; } - private List getMappingMethods(MapperConfiguration mapperConfig, List methods) { - List mappingMethods = new ArrayList(); + private List getMappingMethods(MapperOptions mapperAnnotation, List methods) { + List mappingMethods = new ArrayList<>(); for ( SourceMethod method : methods ) { if ( !method.overridesMethod() ) { continue; } - mergeInheritedOptions( method, mapperConfig, methods, new ArrayList() ); + mergeInheritedOptions( method, mapperAnnotation, methods, new ArrayList<>(), null ); - MappingOptions mappingOptions = method.getMappingOptions(); + MappingMethodOptions mappingOptions = method.getOptions(); boolean hasFactoryMethod = false; if ( method.isIterableMapping() ) { + this.messager.note( 1, Message.ITERABLEMAPPING_CREATE_NOTE, method ); + + IterableMappingMethod iterableMappingMethod = createWithElementMappingMethod( method, mappingOptions, @@ -299,7 +364,7 @@ else if ( method.isMapMapping() ) { FormattingParameters keyFormattingParameters = null; SelectionParameters valueSelectionParameters = null; FormattingParameters valueFormattingParameters = null; - NullValueMappingStrategyPrism nullValueMappingStrategy = null; + NullValueMappingStrategyGem nullValueMappingStrategy = null; if ( mappingOptions.getMapMapping() != null ) { keySelectionParameters = mappingOptions.getMapMapping().getKeySelectionParameters(); @@ -309,6 +374,7 @@ else if ( method.isMapMapping() ) { nullValueMappingStrategy = mappingOptions.getMapMapping().getNullValueMappingStrategy(); } + this.messager.note( 1, Message.MAPMAPPING_CREATE_NOTE, method ); MapMappingMethod mapMappingMethod = builder .mappingContext( mappingContext ) .method( method ) @@ -316,7 +382,6 @@ else if ( method.isMapMapping() ) { .keySelectionParameters( keySelectionParameters ) .valueFormattingParameters( valueFormattingParameters ) .valueSelectionParameters( valueSelectionParameters ) - .nullValueMappingStrategy( nullValueMappingStrategy ) .build(); hasFactoryMethod = mapMappingMethod.getFactoryMethod() != null; @@ -324,30 +389,26 @@ else if ( method.isMapMapping() ) { } else if ( method.isValueMapping() ) { // prefer value mappings over enum mapping + this.messager.note( 1, Message.VALUEMAPPING_CREATE_NOTE, method ); ValueMappingMethod valueMappingMethod = new ValueMappingMethod.Builder() .mappingContext( mappingContext ) .method( method ) .valueMappings( mappingOptions.getValueMappings() ) + .enumMapping( mappingOptions.getEnumMappingOptions() ) .build(); - mappingMethods.add( valueMappingMethod ); - } - else if ( method.isEnumMapping() ) { + if ( valueMappingMethod != null ) { + mappingMethods.add( valueMappingMethod ); + } + } + else if ( method.isRemovedEnumMapping() ) { messager.printMessage( method.getExecutable(), - Message.ENUMMAPPING_DEPRECATED ); - - EnumMappingMethod.Builder builder = new EnumMappingMethod.Builder(); - MappingMethod enumMappingMethod = builder - .mappingContext( mappingContext ) - .sourceMethod( method ) - .build(); - - if ( enumMappingMethod != null ) { - mappingMethods.add( enumMappingMethod ); - } + Message.ENUMMAPPING_REMOVED + ); } else if ( method.isStreamMapping() ) { + this.messager.note( 1, Message.STREAMMAPPING_CREATE_NOTE, method ); StreamMappingMethod streamMappingMethod = createWithElementMappingMethod( method, mappingOptions, @@ -360,26 +421,17 @@ else if ( method.isStreamMapping() ) { mappingMethods.add( streamMappingMethod ); } else { - - NullValueMappingStrategyPrism nullValueMappingStrategy = null; - SelectionParameters selectionParameters = null; - - if ( mappingOptions.getBeanMapping() != null ) { - nullValueMappingStrategy = mappingOptions.getBeanMapping().getNullValueMappingStrategy(); - selectionParameters = mappingOptions.getBeanMapping().getSelectionParameters(); - } - BeanMappingMethod.Builder builder = new BeanMappingMethod.Builder(); - BeanMappingMethod beanMappingMethod = builder + this.messager.note( 1, Message.BEANMAPPING_CREATE_NOTE, method ); + BeanMappingMethod.Builder beanMappingBuilder = new BeanMappingMethod.Builder(); + BeanMappingMethod beanMappingMethod = beanMappingBuilder .mappingContext( mappingContext ) .sourceMethod( method ) - .nullValueMappingStrategy( nullValueMappingStrategy ) - .selectionParameters( selectionParameters ) .build(); + // We can consider that the bean mapping method can always be constructed. If there is a problem + // it would have been reported in its build + hasFactoryMethod = true; if ( beanMappingMethod != null ) { - // We can consider that the bean mapping method can always be constructed. If there is a problem - // it would have been reported in its build - hasFactoryMethod = true; mappingMethods.add( beanMappingMethod ); } } @@ -394,17 +446,32 @@ else if ( method.isStreamMapping() ) { return mappingMethods; } + private Javadoc getJavadoc(TypeElement element) { + JavadocGem javadocGem = JavadocGem.instanceOn( element ); + + if ( javadocGem == null || !isConsistent( javadocGem, element, messager ) ) { + return null; + } + + Javadoc javadoc = new Javadoc.Builder() + .value( javadocGem.value().getValue() ) + .authors( javadocGem.authors().getValue() ) + .deprecated( javadocGem.deprecated().getValue() ) + .since( javadocGem.since().getValue() ) + .build(); + + return javadoc; + } + private M createWithElementMappingMethod(SourceMethod method, - MappingOptions mappingOptions, ContainerMappingMethodBuilder builder) { + MappingMethodOptions mappingMethodOptions, ContainerMappingMethodBuilder builder) { FormattingParameters formattingParameters = null; SelectionParameters selectionParameters = null; - NullValueMappingStrategyPrism nullValueMappingStrategy = null; - if ( mappingOptions.getIterableMapping() != null ) { - formattingParameters = mappingOptions.getIterableMapping().getFormattingParameters(); - selectionParameters = mappingOptions.getIterableMapping().getSelectionParameters(); - nullValueMappingStrategy = mappingOptions.getIterableMapping().getNullValueMappingStrategy(); + if ( mappingMethodOptions.getIterableMapping() != null ) { + formattingParameters = mappingMethodOptions.getIterableMapping().getFormattingParameters(); + selectionParameters = mappingMethodOptions.getIterableMapping().getSelectionParameters(); } return builder @@ -412,12 +479,12 @@ private M createWithElementMappingMethod(Sour .method( method ) .formattingParameters( formattingParameters ) .selectionParameters( selectionParameters ) - .nullValueMappingStrategy( nullValueMappingStrategy ) .build(); } - private void mergeInheritedOptions(SourceMethod method, MapperConfiguration mapperConfig, - List availableMethods, List initializingMethods) { + private void mergeInheritedOptions(SourceMethod method, MapperOptions mapperConfig, + List availableMethods, List initializingMethods, + AnnotationMirror annotationMirror) { if ( initializingMethods.contains( method ) ) { // cycle detected @@ -432,61 +499,41 @@ private void mergeInheritedOptions(SourceMethod method, MapperConfiguration mapp initializingMethods.add( method ); - MappingOptions mappingOptions = method.getMappingOptions(); + MappingMethodOptions mappingOptions = method.getOptions(); List applicableReversePrototypeMethods = method.getApplicableReversePrototypeMethods(); - MappingOptions inverseMappingOptions = - getInverseMappingOptions( join( availableMethods, applicableReversePrototypeMethods ), + SourceMethod inverseTemplateMethod = + getInverseTemplateMethod( join( availableMethods, applicableReversePrototypeMethods ), method, initializingMethods, mapperConfig ); List applicablePrototypeMethods = method.getApplicablePrototypeMethods(); - MappingOptions forwardMappingOptions = - getTemplateMappingOptions( + SourceMethod forwardTemplateMethod = + getForwardTemplateMethod( join( availableMethods, applicablePrototypeMethods ), method, initializingMethods, mapperConfig ); // apply defined (@InheritConfiguration, @InheritInverseConfiguration) mappings - if ( forwardMappingOptions != null ) { - mappingOptions.applyInheritedOptions( - forwardMappingOptions, - false, - method, - messager, - typeFactory, - accessorNaming - ); + if ( forwardTemplateMethod != null ) { + mappingOptions.applyInheritedOptions( method, forwardTemplateMethod, false, annotationMirror ); } - if ( inverseMappingOptions != null ) { - mappingOptions.applyInheritedOptions( - inverseMappingOptions, - true, - method, - messager, - typeFactory, - accessorNaming - ); + if ( inverseTemplateMethod != null ) { + mappingOptions.applyInheritedOptions( method, inverseTemplateMethod, true, annotationMirror ); } // apply auto inherited options - MappingInheritanceStrategyPrism inheritanceStrategy = mapperConfig.getMappingInheritanceStrategy(); + MappingInheritanceStrategyGem inheritanceStrategy = mapperConfig.getMappingInheritanceStrategy(); if ( inheritanceStrategy.isAutoInherit() ) { // but.. there should not be an @InheritedConfiguration - if ( forwardMappingOptions == null && inheritanceStrategy.isApplyForward() ) { + if ( forwardTemplateMethod == null && inheritanceStrategy.isApplyForward() ) { if ( applicablePrototypeMethods.size() == 1 ) { - mappingOptions.applyInheritedOptions( - first( applicablePrototypeMethods ).getMappingOptions(), - false, - method, - messager, - typeFactory, - accessorNaming - ); + mappingOptions.applyInheritedOptions( method, first( applicablePrototypeMethods ), false, + annotationMirror ); } else if ( applicablePrototypeMethods.size() > 1 ) { messager.printMessage( @@ -497,16 +544,10 @@ else if ( applicablePrototypeMethods.size() > 1 ) { } // or no @InheritInverseConfiguration - if ( inverseMappingOptions == null && inheritanceStrategy.isApplyReverse() ) { + if ( inverseTemplateMethod == null && inheritanceStrategy.isApplyReverse() ) { if ( applicableReversePrototypeMethods.size() == 1 ) { - mappingOptions.applyInheritedOptions( - first( applicableReversePrototypeMethods ).getMappingOptions(), - true, - method, - messager, - typeFactory, - accessorNaming - ); + mappingOptions.applyInheritedOptions( method, first( applicableReversePrototypeMethods ), true, + annotationMirror ); } else if ( applicableReversePrototypeMethods.size() > 1 ) { messager.printMessage( @@ -518,14 +559,8 @@ else if ( applicableReversePrototypeMethods.size() > 1 ) { } // @BeanMapping( ignoreByDefault = true ) - if ( mappingOptions.getBeanMapping() != null && mappingOptions.getBeanMapping().isignoreByDefault() ) { - mappingOptions.applyIgnoreAll( - mappingOptions, - method, - messager, - typeFactory, - accessorNaming - ); + if ( mappingOptions.getBeanMapping() != null && mappingOptions.getBeanMapping().isIgnoredByDefault() ) { + mappingOptions.applyIgnoreAll( method, typeFactory, mappingContext.getMessager() ); } mappingOptions.markAsFullyInitialized(); @@ -544,25 +579,24 @@ private void reportErrorIfNoImplementationTypeIsRegisteredForInterfaceReturnType * {@code @InheritInverseConfiguration} and exactly one such configuring method can unambiguously be selected (as * per the source/target type and optionally the name given via {@code @InheritInverseConfiguration}). */ - private MappingOptions getInverseMappingOptions(List rawMethods, SourceMethod method, - List initializingMethods, - MapperConfiguration mapperConfig) { + private SourceMethod getInverseTemplateMethod(List rawMethods, SourceMethod method, + List initializingMethods, + MapperOptions mapperConfig) { SourceMethod resultMethod = null; - InheritInverseConfigurationPrism reversePrism = InheritInverseConfigurationPrism.getInstanceOn( - method.getExecutable() - ); + InheritInverseConfigurationGem inverseConfiguration = + InheritInverseConfigurationGem.instanceOn( method.getExecutable() ); - if ( reversePrism != null ) { + if ( inverseConfiguration != null ) { - // method is configured as being reverse method, collect candidates - List candidates = new ArrayList(); + // method is configured as being inverse method, collect candidates + List candidates = new ArrayList<>(); for ( SourceMethod oneMethod : rawMethods ) { - if ( method.reverses( oneMethod ) ) { + if ( method.inverses( oneMethod ) ) { candidates.add( oneMethod ); } } - String name = reversePrism.name(); + String name = inverseConfiguration.name().get(); if ( candidates.size() == 1 ) { // no ambiguity: if no configuredBy is specified, or configuredBy specified and match if ( name.isEmpty() ) { @@ -572,13 +606,13 @@ else if ( candidates.get( 0 ).getName().equals( name ) ) { resultMethod = candidates.get( 0 ); } else { - reportErrorWhenNonMatchingName( candidates.get( 0 ), method, reversePrism ); + reportErrorWhenNonMatchingName( candidates.get( 0 ), method, inverseConfiguration ); } } else if ( candidates.size() > 1 ) { // ambiguity: find a matching method that matches configuredBy - List nameFilteredcandidates = new ArrayList(); + List nameFilteredcandidates = new ArrayList<>(); for ( SourceMethod candidate : candidates ) { if ( candidate.getName().equals( name ) ) { nameFilteredcandidates.add( candidate ); @@ -589,27 +623,34 @@ else if ( candidates.size() > 1 ) { resultMethod = nameFilteredcandidates.get( 0 ); } else if ( nameFilteredcandidates.size() > 1 ) { - reportErrorWhenSeveralNamesMatch( nameFilteredcandidates, method, reversePrism ); + reportErrorWhenSeveralNamesMatch( nameFilteredcandidates, method, inverseConfiguration ); } else { - reportErrorWhenAmbigousReverseMapping( candidates, method, reversePrism ); + reportErrorWhenAmbiguousReverseMapping( candidates, method, inverseConfiguration ); } } } - return extractInitializedOptions( resultMethod, rawMethods, mapperConfig, initializingMethods ); + return extractInitializedOptions( resultMethod, rawMethods, mapperConfig, initializingMethods, + getAnnotationMirror( inverseConfiguration ) ); } - private MappingOptions extractInitializedOptions(SourceMethod resultMethod, + private AnnotationMirror getAnnotationMirror(InheritInverseConfigurationGem inverseConfiguration) { + return inverseConfiguration == null ? null : inverseConfiguration.mirror(); + } + + private SourceMethod extractInitializedOptions(SourceMethod resultMethod, List rawMethods, - MapperConfiguration mapperConfig, - List initializingMethods) { + MapperOptions mapperConfig, + List initializingMethods, + AnnotationMirror annotationMirror) { if ( resultMethod != null ) { - if ( !resultMethod.getMappingOptions().isFullyInitialized() ) { - mergeInheritedOptions( resultMethod, mapperConfig, rawMethods, initializingMethods ); + if ( !resultMethod.getOptions().isFullyInitialized() ) { + mergeInheritedOptions( resultMethod, mapperConfig, rawMethods, initializingMethods, + annotationMirror ); } - return resultMethod.getMappingOptions(); + return resultMethod; } return null; @@ -621,17 +662,16 @@ private MappingOptions extractInitializedOptions(SourceMethod resultMethod, * source/target type and optionally the name given via {@code @InheritConfiguration}). The method cannot be marked * forward mapping itself (hence 'other'). And neither can it contain an {@code @InheritReverseConfiguration} */ - private MappingOptions getTemplateMappingOptions(List rawMethods, SourceMethod method, - List initializingMethods, - MapperConfiguration mapperConfig) { + private SourceMethod getForwardTemplateMethod(List rawMethods, SourceMethod method, + List initializingMethods, + MapperOptions mapperConfig) { SourceMethod resultMethod = null; - InheritConfigurationPrism forwardPrism = InheritConfigurationPrism.getInstanceOn( - method.getExecutable() - ); + InheritConfigurationGem inheritConfiguration = + InheritConfigurationGem.instanceOn( method.getExecutable() ); - if ( forwardPrism != null ) { + if ( inheritConfiguration != null ) { - List candidates = new ArrayList(); + List candidates = new ArrayList<>(); for ( SourceMethod oneMethod : rawMethods ) { // method must be similar but not equal if ( method.canInheritFrom( oneMethod ) && !( oneMethod.equals( method ) ) ) { @@ -639,7 +679,7 @@ private MappingOptions getTemplateMappingOptions(List rawMethods, } } - String name = forwardPrism.name(); + String name = inheritConfiguration.name().get(); if ( candidates.size() == 1 ) { // no ambiguity: if no configuredBy is specified, or configuredBy specified and match SourceMethod sourceMethod = first( candidates ); @@ -650,46 +690,51 @@ else if ( sourceMethod.getName().equals( name ) ) { resultMethod = sourceMethod; } else { - reportErrorWhenNonMatchingName( sourceMethod, method, forwardPrism ); + reportErrorWhenNonMatchingName( sourceMethod, method, inheritConfiguration ); } } else if ( candidates.size() > 1 ) { // ambiguity: find a matching method that matches configuredBy - List nameFilteredcandidates = new ArrayList(); + List nameFilteredCandidates = new ArrayList<>(); for ( SourceMethod candidate : candidates ) { if ( candidate.getName().equals( name ) ) { - nameFilteredcandidates.add( candidate ); + nameFilteredCandidates.add( candidate ); } } - if ( nameFilteredcandidates.size() == 1 ) { - resultMethod = first( nameFilteredcandidates ); + if ( nameFilteredCandidates.size() == 1 ) { + resultMethod = first( nameFilteredCandidates ); } - else if ( nameFilteredcandidates.size() > 1 ) { - reportErrorWhenSeveralNamesMatch( nameFilteredcandidates, method, forwardPrism ); + else if ( nameFilteredCandidates.size() > 1 ) { + reportErrorWhenSeveralNamesMatch( nameFilteredCandidates, method, inheritConfiguration ); } else { - reportErrorWhenAmbigousMapping( candidates, method, forwardPrism ); + reportErrorWhenAmbiguousMapping( candidates, method, inheritConfiguration ); } } } - return extractInitializedOptions( resultMethod, rawMethods, mapperConfig, initializingMethods ); + return extractInitializedOptions( resultMethod, rawMethods, mapperConfig, initializingMethods, + getAnnotationMirror( inheritConfiguration ) ); + } + + private AnnotationMirror getAnnotationMirror(InheritConfigurationGem inheritConfiguration) { + return inheritConfiguration == null ? null : inheritConfiguration.mirror(); } - private void reportErrorWhenAmbigousReverseMapping(List candidates, SourceMethod method, - InheritInverseConfigurationPrism reversePrism) { + private void reportErrorWhenAmbiguousReverseMapping(List candidates, SourceMethod method, + InheritInverseConfigurationGem inverseGem) { - List candidateNames = new ArrayList(); + List candidateNames = new ArrayList<>(); for ( SourceMethod candidate : candidates ) { candidateNames.add( candidate.getName() ); } - String name = reversePrism.name(); + String name = inverseGem.name().get(); if ( name.isEmpty() ) { messager.printMessage( method.getExecutable(), - reversePrism.mirror, + inverseGem.mirror(), Message.INHERITINVERSECONFIGURATION_DUPLICATES, Strings.join( candidateNames, "(), " ) @@ -697,7 +742,7 @@ private void reportErrorWhenAmbigousReverseMapping(List candidates } else { messager.printMessage( method.getExecutable(), - reversePrism.mirror, + inverseGem.mirror(), Message.INHERITINVERSECONFIGURATION_INVALID_NAME, Strings.join( candidateNames, "(), " ), name @@ -707,40 +752,40 @@ private void reportErrorWhenAmbigousReverseMapping(List candidates } private void reportErrorWhenSeveralNamesMatch(List candidates, SourceMethod method, - InheritInverseConfigurationPrism reversePrism) { + InheritInverseConfigurationGem inverseGem) { messager.printMessage( method.getExecutable(), - reversePrism.mirror, + inverseGem.mirror(), Message.INHERITINVERSECONFIGURATION_DUPLICATE_MATCHES, - reversePrism.name(), + inverseGem.name().get(), Strings.join( candidates, ", " ) ); } private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method, - InheritInverseConfigurationPrism reversePrism) { + InheritInverseConfigurationGem inverseGem) { messager.printMessage( method.getExecutable(), - reversePrism.mirror, + inverseGem.mirror(), Message.INHERITINVERSECONFIGURATION_NO_NAME_MATCH, - reversePrism.name(), + inverseGem.name().get(), onlyCandidate.getName() ); } - private void reportErrorWhenAmbigousMapping(List candidates, SourceMethod method, - InheritConfigurationPrism prism) { + private void reportErrorWhenAmbiguousMapping(List candidates, SourceMethod method, + InheritConfigurationGem gem) { - List candidateNames = new ArrayList(); + List candidateNames = new ArrayList<>(); for ( SourceMethod candidate : candidates ) { candidateNames.add( candidate.getName() ); } - String name = prism.name(); + String name = gem.name().get(); if ( name.isEmpty() ) { messager.printMessage( method.getExecutable(), - prism.mirror, + gem.mirror(), Message.INHERITCONFIGURATION_DUPLICATES, Strings.join( candidateNames, "(), " ) ); @@ -748,7 +793,7 @@ private void reportErrorWhenAmbigousMapping(List candidates, Sourc else { messager.printMessage( method.getExecutable(), - prism.mirror, + gem.mirror(), Message.INHERITCONFIGURATION_INVALIDNAME, Strings.join( candidateNames, "(), " ), name @@ -757,26 +802,37 @@ private void reportErrorWhenAmbigousMapping(List candidates, Sourc } private void reportErrorWhenSeveralNamesMatch(List candidates, SourceMethod method, - InheritConfigurationPrism prism) { + InheritConfigurationGem gem) { messager.printMessage( method.getExecutable(), - prism.mirror, + gem.mirror(), Message.INHERITCONFIGURATION_DUPLICATE_MATCHES, - prism.name(), + gem.name().get(), Strings.join( candidates, ", " ) ); } private void reportErrorWhenNonMatchingName(SourceMethod onlyCandidate, SourceMethod method, - InheritConfigurationPrism prims) { + InheritConfigurationGem gem) { messager.printMessage( method.getExecutable(), - prims.mirror, + gem.mirror(), Message.INHERITCONFIGURATION_NO_NAME_MATCH, - prims.name(), + gem.name().get(), onlyCandidate.getName() ); } + + private boolean isConsistent( JavadocGem gem, TypeElement element, FormattingMessager messager ) { + if ( !gem.value().hasValue() + && !gem.authors().hasValue() + && !gem.deprecated().hasValue() + && !gem.since().hasValue() ) { + messager.printMessage( element, gem.mirror(), Message.JAVADOC_NO_ELEMENTS ); + return false; + } + return true; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperRenderingProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperRenderingProcessor.java index a0d90adc17..bab6af7b09 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperRenderingProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperRenderingProcessor.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; import java.io.IOException; - import javax.annotation.processing.Filer; import javax.lang.model.element.TypeElement; import javax.tools.JavaFileObject; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java index 03ea857d51..ee0bf34634 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MapperServiceProcessor.java @@ -1,34 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; import java.io.IOException; - import javax.annotation.processing.Filer; import javax.lang.model.element.TypeElement; import javax.tools.FileObject; import javax.tools.StandardLocation; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; +import org.mapstruct.ap.internal.model.Decorator; import org.mapstruct.ap.internal.model.GeneratedType; import org.mapstruct.ap.internal.model.Mapper; import org.mapstruct.ap.internal.model.ServicesEntry; -import org.mapstruct.ap.internal.util.MapperConfiguration; +import org.mapstruct.ap.internal.model.common.Type; +import org.mapstruct.ap.internal.model.source.MapperOptions; import org.mapstruct.ap.internal.writer.ModelWriter; /** @@ -50,9 +39,9 @@ public Void process(ProcessorContext context, TypeElement mapperTypeElement, Map } else { String componentModel = - MapperConfiguration.getInstanceOn( mapperTypeElement ).componentModel( context.getOptions() ); + MapperOptions.getInstanceOn( mapperTypeElement, context.getOptions() ).componentModel( ); - spiGenerationNeeded = "default".equals( componentModel ); + spiGenerationNeeded = MappingConstantsGem.ComponentModelGem.DEFAULT.equals( componentModel ); } if ( !context.isErroneous() && spiGenerationNeeded && mapper.hasCustomImplementation() ) { @@ -68,15 +57,28 @@ public int getPriority() { private void writeToSourceFile(Filer filer, Mapper model) { ModelWriter modelWriter = new ModelWriter(); - ServicesEntry servicesEntry = getServicesEntry( model.getDecorator() == null ? model : model.getDecorator() ); + ServicesEntry servicesEntry = getServicesEntry( model ); createSourceFile( servicesEntry, modelWriter, filer ); } - private ServicesEntry getServicesEntry(GeneratedType model) { - String mapperName = model.getInterfaceName() != null ? model.getInterfaceName() : model.getSuperClassName(); + private ServicesEntry getServicesEntry(Mapper mapper) { + if ( mapper.getDecorator() != null ) { + return getServicesEntry( mapper.getDecorator() ); + } + + return getServicesEntry( mapper.getMapperDefinitionType(), mapper ); + } + + private ServicesEntry getServicesEntry(Decorator decorator) { + return getServicesEntry( decorator.getMapperType(), decorator ); + } + + private ServicesEntry getServicesEntry(Type mapperType, GeneratedType model) { + String mapperName = mapperType.getName(); + String mapperPackageName = mapperType.getPackageName(); - return new ServicesEntry(model.getInterfacePackage(), mapperName, + return new ServicesEntry(mapperPackageName, mapperName, model.getPackageName(), model.getName()); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java index 04eb86a13d..d7a0329aeb 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/MethodRetrievalProcessor.java @@ -1,66 +1,65 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; -import static org.mapstruct.ap.internal.util.Executables.getAllEnclosedExecutableElements; - import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; - +import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; +import org.mapstruct.ap.internal.gem.BeanMappingGem; +import org.mapstruct.ap.internal.gem.ConditionGem; +import org.mapstruct.ap.internal.gem.IgnoredGem; +import org.mapstruct.ap.internal.gem.IgnoredListGem; +import org.mapstruct.ap.internal.gem.IterableMappingGem; +import org.mapstruct.ap.internal.gem.MapMappingGem; +import org.mapstruct.ap.internal.gem.MappingGem; +import org.mapstruct.ap.internal.gem.MappingsGem; +import org.mapstruct.ap.internal.gem.ObjectFactoryGem; +import org.mapstruct.ap.internal.gem.SourcePropertyNameGem; +import org.mapstruct.ap.internal.gem.SubclassMappingGem; +import org.mapstruct.ap.internal.gem.SubclassMappingsGem; +import org.mapstruct.ap.internal.gem.TargetPropertyNameGem; +import org.mapstruct.ap.internal.gem.ValueMappingGem; +import org.mapstruct.ap.internal.gem.ValueMappingsGem; import org.mapstruct.ap.internal.model.common.Parameter; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; -import org.mapstruct.ap.internal.model.source.BeanMapping; -import org.mapstruct.ap.internal.model.source.IterableMapping; -import org.mapstruct.ap.internal.model.source.MapMapping; -import org.mapstruct.ap.internal.model.source.Mapping; +import org.mapstruct.ap.internal.model.source.BeanMappingOptions; +import org.mapstruct.ap.internal.model.source.ConditionOptions; +import org.mapstruct.ap.internal.model.source.EnumMappingOptions; +import org.mapstruct.ap.internal.model.source.IterableMappingOptions; +import org.mapstruct.ap.internal.model.source.MapMappingOptions; +import org.mapstruct.ap.internal.model.source.MapperOptions; +import org.mapstruct.ap.internal.model.source.MappingOptions; import org.mapstruct.ap.internal.model.source.ParameterProvidedMethods; import org.mapstruct.ap.internal.model.source.SourceMethod; -import org.mapstruct.ap.internal.model.source.ValueMapping; -import org.mapstruct.ap.internal.prism.BeanMappingPrism; -import org.mapstruct.ap.internal.prism.IterableMappingPrism; -import org.mapstruct.ap.internal.prism.MapMappingPrism; -import org.mapstruct.ap.internal.prism.MappingPrism; -import org.mapstruct.ap.internal.prism.MappingsPrism; -import org.mapstruct.ap.internal.prism.ObjectFactoryPrism; -import org.mapstruct.ap.internal.prism.ValueMappingPrism; -import org.mapstruct.ap.internal.prism.ValueMappingsPrism; +import org.mapstruct.ap.internal.model.source.SubclassMappingOptions; +import org.mapstruct.ap.internal.model.source.SubclassValidator; +import org.mapstruct.ap.internal.model.source.ValueMappingOptions; +import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.util.AccessorNamingUtils; import org.mapstruct.ap.internal.util.AnnotationProcessingException; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.Executables; import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.MapperConfiguration; import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.MetaAnnotations; +import org.mapstruct.ap.internal.util.RepeatableAnnotations; +import org.mapstruct.ap.internal.util.TypeUtils; +import org.mapstruct.ap.spi.EnumTransformationStrategy; /** * A {@link ModelElementProcessor} which retrieves a list of {@link SourceMethod}s @@ -72,11 +71,22 @@ */ public class MethodRetrievalProcessor implements ModelElementProcessor> { + private static final String MAPPING_FQN = "org.mapstruct.Mapping"; + private static final String MAPPINGS_FQN = "org.mapstruct.Mappings"; + private static final String SUB_CLASS_MAPPING_FQN = "org.mapstruct.SubclassMapping"; + private static final String SUB_CLASS_MAPPINGS_FQN = "org.mapstruct.SubclassMappings"; + private static final String VALUE_MAPPING_FQN = "org.mapstruct.ValueMapping"; + private static final String VALUE_MAPPINGS_FQN = "org.mapstruct.ValueMappings"; + private static final String CONDITION_FQN = "org.mapstruct.Condition"; + private static final String IGNORED_FQN = "org.mapstruct.Ignored"; + private static final String IGNORED_LIST_FQN = "org.mapstruct.IgnoredList"; private FormattingMessager messager; private TypeFactory typeFactory; private AccessorNamingUtils accessorNaming; - private Types typeUtils; - private Elements elementUtils; + private Map enumTransformationStrategies; + private TypeUtils typeUtils; + private ElementUtils elementUtils; + private Options options; @Override public List process(ProcessorContext context, TypeElement mapperTypeElement, Void sourceModel) { @@ -85,18 +95,31 @@ public List process(ProcessorContext context, TypeElement mapperTy this.accessorNaming = context.getAccessorNaming(); this.typeUtils = context.getTypeUtils(); this.elementUtils = context.getElementUtils(); + this.enumTransformationStrategies = context.getEnumTransformationStrategies(); + this.options = context.getOptions(); - MapperConfiguration mapperConfig = MapperConfiguration.getInstanceOn( mapperTypeElement ); + this.messager.note( 0, Message.PROCESSING_NOTE, mapperTypeElement ); - if ( !mapperConfig.isValid() ) { + MapperOptions mapperOptions = MapperOptions.getInstanceOn( mapperTypeElement, context.getOptions() ); + + if ( mapperOptions.hasMapperConfig() ) { + this.messager.note( 0, Message.CONFIG_NOTE, mapperOptions.mapperConfigType().asElement().getSimpleName() ); + } + + if ( !mapperOptions.isValid() ) { throw new AnnotationProcessingException( "Couldn't retrieve @Mapper annotation", mapperTypeElement, - mapperConfig.getAnnotationMirror() ); + mapperOptions.getAnnotationMirror() ); } - List prototypeMethods = retrievePrototypeMethods( mapperTypeElement, mapperConfig ); - return retrieveMethods( mapperTypeElement, mapperTypeElement, mapperConfig, prototypeMethods ); + List prototypeMethods = retrievePrototypeMethods( mapperTypeElement, mapperOptions ); + return retrieveMethods( + typeFactory.getType( mapperTypeElement.asType() ), + mapperTypeElement, + mapperOptions, + prototypeMethods + ); } @Override @@ -105,16 +128,21 @@ public int getPriority() { } private List retrievePrototypeMethods(TypeElement mapperTypeElement, - MapperConfiguration mapperConfig) { - if ( mapperConfig.config() == null ) { + MapperOptions mapperAnnotation) { + if ( !mapperAnnotation.hasMapperConfig() ) { return Collections.emptyList(); } - TypeElement typeElement = asTypeElement( mapperConfig.config() ); - List methods = new ArrayList(); - for ( ExecutableElement executable : getAllEnclosedExecutableElements( elementUtils, typeElement ) ) { + TypeElement typeElement = asTypeElement( mapperAnnotation.mapperConfigType() ); + List methods = new ArrayList<>(); + for ( ExecutableElement executable : elementUtils.getAllEnclosedExecutableElements( typeElement ) ) { - ExecutableType methodType = typeFactory.getMethodType( mapperConfig.config(), executable ); + if ( executable.isDefault() || executable.getModifiers().contains( Modifier.STATIC ) ) { + // skip the default and static methods because these are not prototypes. + continue; + } + + ExecutableType methodType = typeFactory.getMethodType( mapperAnnotation.mapperConfigType(), executable ); List parameters = typeFactory.getParameters( methodType, executable ); boolean containsTargetTypeParameter = SourceMethod.containsTargetTypeParameter( parameters ); @@ -127,7 +155,7 @@ private List retrievePrototypeMethods(TypeElement mapperTypeElemen executable, parameters, containsTargetTypeParameter, - mapperConfig, + mapperAnnotation, prototypeMethods, mapperTypeElement ); @@ -143,22 +171,24 @@ private List retrievePrototypeMethods(TypeElement mapperTypeElemen /** * Retrieves the mapping methods declared by the given mapper type. * - * @param usedMapper The type of interest (either the mapper to implement or a used mapper via @uses annotation) + * @param usedMapperType The type of interest (either the mapper to implement, a used mapper via @uses annotation, + * or a parameter type annotated with @Context) * @param mapperToImplement the top level type (mapper) that requires implementation - * @param mapperConfig the mapper config + * @param mapperOptions the mapper config * @param prototypeMethods prototype methods defined in mapper config type * @return All mapping methods declared by the given type */ - private List retrieveMethods(TypeElement usedMapper, TypeElement mapperToImplement, - MapperConfiguration mapperConfig, List prototypeMethods) { - List methods = new ArrayList(); + private List retrieveMethods(Type usedMapperType, TypeElement mapperToImplement, + MapperOptions mapperOptions, List prototypeMethods) { + List methods = new ArrayList<>(); - for ( ExecutableElement executable : getAllEnclosedExecutableElements( elementUtils, usedMapper ) ) { + TypeElement usedMapper = usedMapperType.getTypeElement(); + for ( ExecutableElement executable : elementUtils.getAllEnclosedExecutableElements( usedMapper ) ) { SourceMethod method = getMethod( - usedMapper, + usedMapperType, executable, mapperToImplement, - mapperConfig, + mapperOptions, prototypeMethods ); if ( method != null ) { @@ -168,12 +198,23 @@ private List retrieveMethods(TypeElement usedMapper, TypeElement m //Add all methods of used mappers in order to reference them in the aggregated model if ( usedMapper.equals( mapperToImplement ) ) { - for ( DeclaredType mapper : mapperConfig.uses() ) { - methods.addAll( retrieveMethods( - asTypeElement( mapper ), - mapperToImplement, - mapperConfig, - prototypeMethods ) ); + for ( DeclaredType mapper : mapperOptions.uses() ) { + TypeElement usesMapperElement = asTypeElement( mapper ); + if ( !mapperToImplement.equals( usesMapperElement ) ) { + methods.addAll( retrieveMethods( + typeFactory.getType( mapper ), + mapperToImplement, + mapperOptions, + prototypeMethods ) ); + } + else { + messager.printMessage( + mapperToImplement, + mapperOptions.getAnnotationMirror(), + Message.RETRIEVAL_MAPPER_USES_CYCLE, + mapperToImplement + ); + } } } @@ -184,13 +225,13 @@ private TypeElement asTypeElement(DeclaredType type) { return (TypeElement) type.asElement(); } - private SourceMethod getMethod(TypeElement usedMapper, + private SourceMethod getMethod(Type usedMapperType, ExecutableElement method, TypeElement mapperToImplement, - MapperConfiguration mapperConfig, + MapperOptions mapperOptions, List prototypeMethods) { - - ExecutableType methodType = typeFactory.getMethodType( (DeclaredType) usedMapper.asType(), method ); + TypeElement usedMapper = usedMapperType.getTypeElement(); + ExecutableType methodType = typeFactory.getMethodType( (DeclaredType) usedMapperType.getTypeMirror(), method ); List parameters = typeFactory.getParameters( methodType, method ); Type returnType = typeFactory.getReturnType( methodType ); @@ -203,13 +244,14 @@ private SourceMethod getMethod(TypeElement usedMapper, method, parameters, containsTargetTypeParameter, - mapperConfig, + mapperOptions, prototypeMethods, mapperToImplement ); } // otherwise add reference to existing mapper method else if ( isValidReferencedMethod( parameters ) || isValidFactoryMethod( method, parameters, returnType ) - || isValidLifecycleCallbackMethod( method, returnType ) ) { + || isValidLifecycleCallbackMethod( method ) + || isValidPresenceCheckMethod( method, parameters, returnType ) ) { return getReferencedMethod( usedMapper, methodType, method, mapperToImplement, parameters ); } else { @@ -220,7 +262,7 @@ else if ( isValidReferencedMethod( parameters ) || isValidFactoryMethod( method, private SourceMethod getMethodRequiringImplementation(ExecutableType methodType, ExecutableElement method, List parameters, boolean containsTargetTypeParameter, - MapperConfiguration mapperConfig, + MapperOptions mapperOptions, List prototypeMethods, TypeElement mapperToImplement) { Type returnType = typeFactory.getReturnType( methodType ); @@ -245,53 +287,92 @@ private SourceMethod getMethodRequiringImplementation(ExecutableType methodType, } ParameterProvidedMethods contextProvidedMethods = - retrieveContextProvidedMethods( contextParameters, mapperToImplement, mapperConfig ); + retrieveContextProvidedMethods( contextParameters, mapperToImplement, mapperOptions ); + + BeanMappingOptions beanMappingOptions = BeanMappingOptions.getInstanceOn( + BeanMappingGem.instanceOn( method ), + mapperOptions, + method, + messager, + typeUtils, + typeFactory ); + + Set mappingOptions = getMappings( method, beanMappingOptions ); + + IterableMappingOptions iterableMappingOptions = IterableMappingOptions.fromGem( + IterableMappingGem.instanceOn( method ), + mapperOptions, + method, + messager, + typeUtils + ); + + MapMappingOptions mapMappingOptions = MapMappingOptions.fromGem( + MapMappingGem.instanceOn( method ), + mapperOptions, + method, + messager, + typeUtils + ); + + EnumMappingOptions enumMappingOptions = EnumMappingOptions.getInstanceOn( + method, + mapperOptions, + enumTransformationStrategies, + messager + ); + + // We want to get as much error reporting as possible. + // If targetParameter is not null it means we have an update method + SubclassValidator subclassValidator = new SubclassValidator( messager, typeUtils ); + Set subclassMappingOptions = getSubclassMappings( + sourceParameters, + targetParameter != null ? null : resultType, + method, + beanMappingOptions, + subclassValidator + ); return new SourceMethod.Builder() .setExecutable( method ) .setParameters( parameters ) .setReturnType( returnType ) .setExceptionTypes( exceptionTypes ) - .setMappings( getMappings( method ) ) - .setIterableMapping( - IterableMapping.fromPrism( - IterableMappingPrism.getInstanceOn( method ), - method, - messager, - typeUtils - ) ) - .setMapMapping( - MapMapping.fromPrism( MapMappingPrism.getInstanceOn( method ), method, messager, typeUtils ) ) - .setBeanMapping( - BeanMapping.fromPrism( BeanMappingPrism.getInstanceOn( method ), method, messager, typeUtils ) ) - .setValueMappings( getValueMappings( method ) ) + .setMapper( mapperOptions ) + .setBeanMappingOptions( beanMappingOptions ) + .setMappingOptions( mappingOptions ) + .setIterableMappingOptions( iterableMappingOptions ) + .setMapMappingOptions( mapMappingOptions ) + .setValueMappingOptionss( getValueMappings( method ) ) + .setEnumMappingOptions( enumMappingOptions ) + .setSubclassMappings( subclassMappingOptions ) + .setSubclassValidator( subclassValidator ) .setTypeUtils( typeUtils ) - .setMessager( messager ) .setTypeFactory( typeFactory ) - .setAccessorNaming( accessorNaming ) - .setMapperConfiguration( mapperConfig ) .setPrototypeMethods( prototypeMethods ) .setContextProvidedMethods( contextProvidedMethods ) + .setVerboseLogging( options.isVerbose() ) .build(); } private ParameterProvidedMethods retrieveContextProvidedMethods( - List contextParameters, TypeElement mapperToImplement, MapperConfiguration mapperConfig) { + List contextParameters, TypeElement mapperToImplement, MapperOptions mapperConfig) { ParameterProvidedMethods.Builder builder = ParameterProvidedMethods.builder(); for ( Parameter contextParam : contextParameters ) { - if ( contextParam.getType().isPrimitive() ) { + if ( contextParam.getType().isPrimitive() || contextParam.getType().isArrayType() ) { continue; } List contextParamMethods = retrieveMethods( - contextParam.getType().getTypeElement(), + contextParam.getType(), mapperToImplement, mapperConfig, - Collections. emptyList() ); + Collections.emptyList() ); - List contextProvidedMethods = new ArrayList( contextParamMethods.size() ); + List contextProvidedMethods = new ArrayList<>( contextParamMethods.size() ); for ( SourceMethod sourceMethod : contextParamMethods ) { - if ( sourceMethod.isLifecycleCallbackMethod() || sourceMethod.isObjectFactory() ) { + if ( sourceMethod.isLifecycleCallbackMethod() || sourceMethod.isObjectFactory() + || sourceMethod.getConditionOptions().isAnyStrategyApplicable() ) { contextProvidedMethods.add( sourceMethod ); } } @@ -319,18 +400,19 @@ private SourceMethod getReferencedMethod(TypeElement usedMapper, ExecutableType return new SourceMethod.Builder() .setDeclaringMapper( usedMapper.equals( mapperToImplement ) ? null : usedMapperAsType ) - .setDefininingType( definingType ) + .setDefiningType( definingType ) .setExecutable( method ) .setParameters( parameters ) .setReturnType( returnType ) .setExceptionTypes( exceptionTypes ) .setTypeUtils( typeUtils ) .setTypeFactory( typeFactory ) - .setAccessorNaming( accessorNaming ) + .setConditionOptions( getConditionOptions( method, parameters ) ) + .setVerboseLogging( options.isVerbose() ) .build(); } - private boolean isValidLifecycleCallbackMethod(ExecutableElement method, Type returnType) { + private boolean isValidLifecycleCallbackMethod(ExecutableElement method) { return Executables.isLifecycleCallbackMethod( method ); } @@ -344,13 +426,45 @@ private boolean isValidFactoryMethod(ExecutableElement method, List p } private boolean hasFactoryAnnotation(ExecutableElement method) { - return ObjectFactoryPrism.getInstanceOn( method ) != null; + return ObjectFactoryGem.instanceOn( method ) != null; + } + + private boolean isValidPresenceCheckMethod(ExecutableElement method, List parameters, Type returnType) { + for ( Parameter param : parameters ) { + + if ( param.isSourcePropertyName() && !param.getType().isString() ) { + messager.printMessage( + param.getElement(), + SourcePropertyNameGem.instanceOn( param.getElement() ).mirror(), + Message.RETRIEVAL_SOURCE_PROPERTY_NAME_WRONG_TYPE + ); + return false; + } + + if ( param.isTargetPropertyName() && !param.getType().isString() ) { + messager.printMessage( + param.getElement(), + TargetPropertyNameGem.instanceOn( param.getElement() ).mirror(), + Message.RETRIEVAL_TARGET_PROPERTY_NAME_WRONG_TYPE + ); + return false; + } + } + return isBoolean( returnType ) && hasConditionAnnotation( method ); + } + + private boolean hasConditionAnnotation(ExecutableElement method) { + return ConditionGem.instanceOn( method ) != null; } private boolean isVoid(Type returnType) { return returnType.getTypeMirror().getKind() == TypeKind.VOID; } + private boolean isBoolean(Type returnType) { + return Boolean.class.getCanonicalName().equals( returnType.getBoxedEquivalent().getFullyQualifiedName() ); + } + private boolean isValidReferencedOrFactoryMethod(int sourceParamCount, int targetParamCount, List parameters) { int validSourceParameters = 0; @@ -395,8 +509,7 @@ private Type selectResultType(Type returnType, Parameter targetParameter) { private boolean checkParameterAndReturnType(ExecutableElement method, List sourceParameters, Parameter targetParameter, List contextParameters, - Type resultType, Type returnType, - boolean containsTargetTypeParameter) { + Type resultType, Type returnType, boolean containsTargetTypeParameter) { if ( sourceParameters.isEmpty() ) { messager.printMessage( method, Message.RETRIEVAL_NO_INPUT_ARGS ); return false; @@ -414,8 +527,8 @@ private boolean checkParameterAndReturnType(ExecutableElement method, List contextParameterTypes = new HashSet(); + Set contextParameterTypes = new HashSet<>(); for ( Parameter contextParameter : contextParameters ) { if ( !contextParameterTypes.add( contextParameter.getType() ) ) { messager.printMessage( method, Message.RETRIEVAL_CONTEXT_PARAMS_WITH_SAME_TYPE ); @@ -440,40 +553,49 @@ private boolean checkParameterAndReturnType(ExecutableElement method, List> getMappings(ExecutableElement method) { - Map> mappings = new HashMap>(); + private Set getMappings(ExecutableElement method, BeanMappingOptions beanMapping) { + Set processedAnnotations = new RepeatableMappings( beanMapping ) + .getProcessedAnnotations( method ); + processedAnnotations.addAll( new IgnoredConditions( processedAnnotations ) + .getProcessedAnnotations( method ) ); + return processedAnnotations; + } + + /** + * Retrieves the subclass mappings configured via {@code @SubclassMapping} from the given method. + * + * @param method The method of interest + * @param beanMapping options coming from bean mapping method + * + * @return The subclass mappings for the given method + */ + private Set getSubclassMappings(List sourceParameters, Type resultType, + ExecutableElement method, BeanMappingOptions beanMapping, + SubclassValidator validator) { + return new RepeatableSubclassMappings( beanMapping, sourceParameters, resultType, validator ) + .getProcessedAnnotations( method ); + } - MappingPrism mappingAnnotation = MappingPrism.getInstanceOn( method ); - MappingsPrism mappingsAnnotation = MappingsPrism.getInstanceOn( method ); + /** + * Retrieves the conditions configured via {@code @Condition} from the given method. + * + * @param method The method of interest + * @param parameters + * @return The condition options for the given method + */ - if ( mappingAnnotation != null ) { - if ( !mappings.containsKey( mappingAnnotation.target() ) ) { - mappings.put( mappingAnnotation.target(), new ArrayList() ); - } - Mapping mapping = Mapping.fromMappingPrism( mappingAnnotation, method, messager, typeUtils ); - if ( mapping != null ) { - mappings.get( mappingAnnotation.target() ).add( mapping ); - } + private Set getConditionOptions(ExecutableElement method, List parameters) { + return new MetaConditions( parameters ).getProcessedAnnotations( method ); + } + + private class RepeatableMappings extends RepeatableAnnotations { + private BeanMappingOptions beanMappingOptions; + + RepeatableMappings(BeanMappingOptions beanMappingOptions) { + super( elementUtils, MAPPING_FQN, MAPPINGS_FQN ); + this.beanMappingOptions = beanMappingOptions; } - if ( mappingsAnnotation != null ) { - mappings.putAll( Mapping.fromMappingsPrism( mappingsAnnotation, method, messager, typeUtils ) ); + @Override + protected MappingGem singularInstanceOn(Element element) { + return MappingGem.instanceOn( element ); } - return mappings; + @Override + protected MappingsGem multipleInstanceOn(Element element) { + return MappingsGem.instanceOn( element ); + } + + @Override + protected void addInstance(MappingGem gem, Element method, Set mappings) { + MappingOptions.addInstance( + gem, + (ExecutableElement) method, + beanMappingOptions, + messager, + typeUtils, + mappings ); + } + + @Override + protected void addInstances(MappingsGem gem, Element method, Set mappings) { + MappingOptions.addInstances( + gem, + (ExecutableElement) method, + beanMappingOptions, + messager, + typeUtils, + mappings ); + } + } + + private class RepeatableSubclassMappings + extends RepeatableAnnotations { + private final List sourceParameters; + private final Type resultType; + private SubclassValidator validator; + private BeanMappingOptions beanMappingOptions; + + RepeatableSubclassMappings(BeanMappingOptions beanMappingOptions, List sourceParameters, + Type resultType, SubclassValidator validator) { + super( elementUtils, SUB_CLASS_MAPPING_FQN, SUB_CLASS_MAPPINGS_FQN ); + this.beanMappingOptions = beanMappingOptions; + this.sourceParameters = sourceParameters; + this.resultType = resultType; + this.validator = validator; + } + + @Override + protected SubclassMappingGem singularInstanceOn(Element element) { + return SubclassMappingGem.instanceOn( element ); + } + + @Override + protected SubclassMappingsGem multipleInstanceOn(Element element) { + return SubclassMappingsGem.instanceOn( element ); + } + + @Override + protected void addInstance(SubclassMappingGem gem, + Element method, + Set mappings) { + SubclassMappingOptions.addInstance( + gem, + (ExecutableElement) method, + beanMappingOptions, + messager, + typeUtils, + mappings, + sourceParameters, + resultType, + validator ); + } + + @Override + protected void addInstances(SubclassMappingsGem gem, + Element method, + Set mappings) { + SubclassMappingOptions.addInstances( + gem, + (ExecutableElement) method, + beanMappingOptions, + messager, + typeUtils, + mappings, + sourceParameters, + resultType, + validator ); + } } /** @@ -542,23 +777,116 @@ private Map> getMappings(ExecutableElement method) { * * @return The mappings for the given method, keyed by target property name */ - private List getValueMappings(ExecutableElement method) { - List valueMappings = new ArrayList(); + private List getValueMappings(ExecutableElement method) { + Set processedAnnotations = new RepeatValueMappings().getProcessedAnnotations( method ); + return new ArrayList<>(processedAnnotations); + } + + private class RepeatValueMappings + extends RepeatableAnnotations { + + protected RepeatValueMappings() { + super( elementUtils, VALUE_MAPPING_FQN, VALUE_MAPPINGS_FQN ); + } - ValueMappingPrism mappingAnnotation = ValueMappingPrism.getInstanceOn( method ); - ValueMappingsPrism mappingsAnnotation = ValueMappingsPrism.getInstanceOn( method ); + @Override + protected ValueMappingGem singularInstanceOn(Element element) { + return ValueMappingGem.instanceOn( element ); + } + + @Override + protected ValueMappingsGem multipleInstanceOn(Element element) { + return ValueMappingsGem.instanceOn( element ); + } + + @Override + protected void addInstance(ValueMappingGem gem, Element source, Set mappings) { + ValueMappingOptions valueMappingOptions = ValueMappingOptions.fromMappingGem( gem ); + mappings.add( valueMappingOptions ); + } + + @Override + protected void addInstances(ValueMappingsGem gems, Element source, Set mappings) { + ValueMappingOptions.fromMappingsGem( gems, (ExecutableElement) source, messager, mappings ); + } + } + + private class MetaConditions extends MetaAnnotations { + + protected final List parameters; + + protected MetaConditions(List parameters) { + super( elementUtils, CONDITION_FQN ); + this.parameters = parameters; + } + + @Override + protected ConditionGem instanceOn(Element element) { + return ConditionGem.instanceOn( element ); + } - if ( mappingAnnotation != null ) { - ValueMapping valueMapping = ValueMapping.fromMappingPrism( mappingAnnotation, method, messager ); - if ( valueMapping != null ) { - valueMappings.add( valueMapping ); + @Override + protected void addInstance(ConditionGem gem, Element source, Set values) { + ConditionOptions options = ConditionOptions.getInstanceOn( + gem, + (ExecutableElement) source, + parameters, + messager + ); + if ( options != null ) { + values.add( options ); } } + } + + private class IgnoredConditions extends RepeatableAnnotations { + + protected final Set processedAnnotations; + + protected IgnoredConditions( Set processedAnnotations ) { + super( elementUtils, IGNORED_FQN, IGNORED_LIST_FQN ); + this.processedAnnotations = processedAnnotations; + } + + @Override + protected IgnoredGem singularInstanceOn(Element element) { + return IgnoredGem.instanceOn( element ); + } + + @Override + protected IgnoredListGem multipleInstanceOn(Element element) { + return IgnoredListGem.instanceOn( element ); + } - if ( mappingsAnnotation != null ) { - ValueMapping.fromMappingsPrism( mappingsAnnotation, method, messager, valueMappings ); + @Override + protected void addInstance(IgnoredGem gem, Element method, Set mappings) { + IgnoredGem ignoredGem = IgnoredGem.instanceOn( method ); + if ( ignoredGem == null ) { + ignoredGem = gem; + } + String prefix = ignoredGem.prefix().get(); + for ( String target : ignoredGem.targets().get() ) { + String realTarget = target; + if ( !prefix.isEmpty() ) { + realTarget = prefix + "." + target; + } + MappingOptions mappingOptions = MappingOptions.forIgnore( realTarget ); + if ( processedAnnotations.contains( mappingOptions ) || mappings.contains( mappingOptions ) ) { + messager.printMessage( method, Message.PROPERTYMAPPING_DUPLICATE_TARGETS, realTarget ); + } + else { + mappings.add( mappingOptions ); + } + } } - return valueMappings; + @Override + protected void addInstances(IgnoredListGem gem, Element method, Set mappings) { + IgnoredListGem ignoredListGem = IgnoredListGem.instanceOn( method ); + for ( IgnoredGem ignoredGem : ignoredListGem.value().get() ) { + addInstance( ignoredGem, method, mappings ); + } + } } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/ModelElementProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/ModelElementProcessor.java index 43a857bf37..10328c4437 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/ModelElementProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/ModelElementProcessor.java @@ -1,34 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; +import java.util.Map; import javax.annotation.processing.Filer; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; import javax.tools.Diagnostic.Kind; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.option.Options; import org.mapstruct.ap.internal.util.AccessorNamingUtils; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.FormattingMessager; +import org.mapstruct.ap.internal.util.NullabilityResolver; +import org.mapstruct.ap.internal.util.TypeUtils; import org.mapstruct.ap.internal.version.VersionInformation; +import org.mapstruct.ap.spi.EnumMappingStrategy; +import org.mapstruct.ap.spi.EnumTransformationStrategy; /** * A processor which performs one task of the mapper generation, e.g. retrieving @@ -45,18 +36,18 @@ public interface ModelElementProcessor { /** * Context object passed to * {@link ModelElementProcessor#process(ProcessorContext, TypeElement, Object)} - * providing access to common infrastructure objects such as {@link Types} + * providing access to common infrastructure objects such as {@link TypeUtils} * etc. * * @author Gunnar Morling */ - public interface ProcessorContext { + interface ProcessorContext { Filer getFiler(); - Types getTypeUtils(); + TypeUtils getTypeUtils(); - Elements getElementUtils(); + ElementUtils getElementUtils(); TypeFactory getTypeFactory(); @@ -64,6 +55,12 @@ public interface ProcessorContext { AccessorNamingUtils getAccessorNaming(); + NullabilityResolver getNullabilityResolver(); + + Map getEnumTransformationStrategies(); + + EnumMappingStrategy getEnumMappingStrategy(); + Options getOptions(); VersionInformation getVersionInformation(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java index 1bf96cd4f5..c31ac51f06 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/SpringComponentProcessor.java @@ -1,30 +1,31 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; import org.mapstruct.ap.internal.model.Annotation; +import org.mapstruct.ap.internal.model.Decorator; import org.mapstruct.ap.internal.model.Mapper; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement; +import org.mapstruct.ap.internal.model.annotation.AnnotationElement.AnnotationElementType; + +import static javax.lang.model.element.ElementKind.PACKAGE; /** * A {@link ModelElementProcessor} which converts the given {@link Mapper} @@ -35,15 +36,21 @@ * @author Andreas Gudian */ public class SpringComponentProcessor extends AnnotationBasedComponentModelProcessor { + + private static final String SPRING_COMPONENT_ANNOTATION = "org.springframework.stereotype.Component"; + private static final String SPRING_PRIMARY_ANNOTATION = "org.springframework.context.annotation.Primary"; + @Override protected String getComponentModelIdentifier() { - return "spring"; + return MappingConstantsGem.ComponentModelGem.SPRING; } @Override protected List getTypeAnnotations(Mapper mapper) { - List typeAnnotations = new ArrayList(); - typeAnnotations.add( component() ); + List typeAnnotations = new ArrayList<>(); + if ( !isAlreadyAnnotatedAsSpringStereotype( mapper ) ) { + typeAnnotations.add( component() ); + } if ( mapper.getDecorator() != null ) { typeAnnotations.add( qualifierDelegate() ); @@ -52,12 +59,37 @@ protected List getTypeAnnotations(Mapper mapper) { return typeAnnotations; } + /** + * Returns the annotations that need to be added to the generated decorator, filtering out any annotations + * that are already present or represented as meta-annotations. + * + * @param decorator the decorator to process + * @return A list of annotations that should be added to the generated decorator. + */ @Override - protected List getDecoratorAnnotations() { - return Arrays.asList( - component(), - primary() - ); + protected List getDecoratorAnnotations(Decorator decorator) { + Set desiredAnnotationNames = new LinkedHashSet<>(); + desiredAnnotationNames.add( SPRING_COMPONENT_ANNOTATION ); + desiredAnnotationNames.add( SPRING_PRIMARY_ANNOTATION ); + List decoratorAnnotations = decorator.getAnnotations(); + if ( !decoratorAnnotations.isEmpty() ) { + Set handledElements = new HashSet<>(); + for ( Annotation annotation : decoratorAnnotations ) { + removeAnnotationsPresentOnElement( + annotation.getType().getTypeElement(), + desiredAnnotationNames, + handledElements + ); + if ( desiredAnnotationNames.isEmpty() ) { + // If all annotations are removed, we can stop further processing + return Collections.emptyList(); + } + } + } + + return desiredAnnotationNames.stream() + .map( this::createAnnotation ) + .collect( Collectors.toList() ); } @Override @@ -80,21 +112,98 @@ protected boolean requiresGenerationOfDecoratorClass() { return true; } + private Annotation createAnnotation(String canonicalName) { + return new Annotation( getTypeFactory().getType( canonicalName ) ); + } + private Annotation autowired() { - return new Annotation( getTypeFactory().getType( "org.springframework.beans.factory.annotation.Autowired" ) ); + return createAnnotation( "org.springframework.beans.factory.annotation.Autowired" ); } private Annotation qualifierDelegate() { return new Annotation( getTypeFactory().getType( "org.springframework.beans.factory.annotation.Qualifier" ), - Collections.singletonList( "\"delegate\"" ) ); + Collections.singletonList( + new AnnotationElement( + AnnotationElementType.STRING, + Collections.singletonList( "delegate" ) + ) ) ); } - private Annotation primary() { - return new Annotation( getTypeFactory().getType( "org.springframework.context.annotation.Primary" ) ); + private Annotation component() { + return createAnnotation( SPRING_COMPONENT_ANNOTATION ); } - private Annotation component() { - return new Annotation( getTypeFactory().getType( "org.springframework.stereotype.Component" ) ); + private boolean isAlreadyAnnotatedAsSpringStereotype(Mapper mapper) { + Set desiredAnnotationNames = new LinkedHashSet<>(); + desiredAnnotationNames.add( SPRING_COMPONENT_ANNOTATION ); + + List mapperAnnotations = mapper.getAnnotations(); + if ( !mapperAnnotations.isEmpty() ) { + Set handledElements = new HashSet<>(); + for ( Annotation annotation : mapperAnnotations ) { + removeAnnotationsPresentOnElement( + annotation.getType().getTypeElement(), + desiredAnnotationNames, + handledElements + ); + if ( desiredAnnotationNames.isEmpty() ) { + // If all annotations are removed, we can stop further processing + return true; + } + } + } + + return false; + } + + /** + * Removes all the annotations and meta-annotations from {@code annotations} which are on the given element. + * + * @param element the element to check + * @param annotations the annotations to check for + * @param handledElements set of already handled elements to avoid infinite recursion + */ + private void removeAnnotationsPresentOnElement(Element element, Set annotations, + Set handledElements) { + if ( annotations.isEmpty() ) { + return; + } + if ( element instanceof TypeElement && + annotations.remove( ( (TypeElement) element ).getQualifiedName().toString() ) ) { + if ( annotations.isEmpty() ) { + // If all annotations are removed, we can stop further processing + return; + } + } + + for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { + Element annotationMirrorElement = annotationMirror.getAnnotationType().asElement(); + // Bypass java lang annotations to improve performance avoiding unnecessary checks + if ( !isAnnotationInPackage( annotationMirrorElement, "java.lang.annotation" ) && + !handledElements.contains( annotationMirrorElement ) ) { + handledElements.add( annotationMirrorElement ); + if ( annotations.remove( ( (TypeElement) annotationMirrorElement ).getQualifiedName().toString() ) ) { + if ( annotations.isEmpty() ) { + // If all annotations are removed, we can stop further processing + return; + } + } + + removeAnnotationsPresentOnElement( element, annotations, handledElements ); + } + } + } + + private PackageElement getPackageOf( Element element ) { + while ( element.getKind() != PACKAGE ) { + element = element.getEnclosingElement(); + } + + return (PackageElement) element; + } + + private boolean isAnnotationInPackage(Element element, String packageFQN) { + return packageFQN.equals( getPackageOf( element ).getQualifiedName().toString() ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java index 04a8dace0b..fb380dc146 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/MappingResolverImpl.java @@ -1,66 +1,71 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.processor.creation; -import static java.util.Collections.singletonList; -import static org.mapstruct.ap.internal.util.Collections.first; - import java.util.ArrayList; import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.Set; - +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Name; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; import org.mapstruct.ap.internal.conversion.ConversionProvider; import org.mapstruct.ap.internal.conversion.Conversions; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; +import org.mapstruct.ap.internal.model.Field; +import org.mapstruct.ap.internal.model.ForgedMethodHistory; import org.mapstruct.ap.internal.model.HelperMethod; import org.mapstruct.ap.internal.model.MapperReference; import org.mapstruct.ap.internal.model.MappingBuilderContext.MappingResolver; import org.mapstruct.ap.internal.model.MethodReference; -import org.mapstruct.ap.internal.model.VirtualMappingMethod; +import org.mapstruct.ap.internal.model.SupportingField; +import org.mapstruct.ap.internal.model.SupportingMappingMethod; import org.mapstruct.ap.internal.model.common.Assignment; import org.mapstruct.ap.internal.model.common.ConversionContext; import org.mapstruct.ap.internal.model.common.DefaultConversionContext; +import org.mapstruct.ap.internal.model.common.FieldReference; import org.mapstruct.ap.internal.model.common.FormattingParameters; import org.mapstruct.ap.internal.model.common.SourceRHS; import org.mapstruct.ap.internal.model.common.Type; import org.mapstruct.ap.internal.model.common.TypeFactory; import org.mapstruct.ap.internal.model.source.Method; -import org.mapstruct.ap.internal.model.source.SelectionParameters; import org.mapstruct.ap.internal.model.source.builtin.BuiltInMappingMethods; import org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod; import org.mapstruct.ap.internal.model.source.selector.MethodSelectors; import org.mapstruct.ap.internal.model.source.selector.SelectedMethod; +import org.mapstruct.ap.internal.model.source.selector.SelectionContext; import org.mapstruct.ap.internal.model.source.selector.SelectionCriteria; import org.mapstruct.ap.internal.util.Collections; +import org.mapstruct.ap.internal.util.ElementUtils; import org.mapstruct.ap.internal.util.FormattingMessager; import org.mapstruct.ap.internal.util.Message; +import org.mapstruct.ap.internal.util.MessageConstants; +import org.mapstruct.ap.internal.util.NativeTypes; import org.mapstruct.ap.internal.util.Strings; +import org.mapstruct.ap.internal.util.TypeUtils; + +import static org.mapstruct.ap.internal.util.Collections.first; +import static org.mapstruct.ap.internal.util.Collections.firstKey; +import static org.mapstruct.ap.internal.util.Collections.firstValue; /** * The one and only implementation of {@link MappingResolver}. The class has been split into an interface an @@ -71,8 +76,10 @@ */ public class MappingResolverImpl implements MappingResolver { + private static final int LIMIT_REPORTING_AMBIGUOUS = 5; + private final FormattingMessager messager; - private final Types typeUtils; + private final TypeUtils typeUtils; private final TypeFactory typeFactory; private final List sourceModel; @@ -82,15 +89,24 @@ public class MappingResolverImpl implements MappingResolver { private final BuiltInMappingMethods builtInMethods; private final MethodSelectors methodSelectors; + private final boolean verboseLogging; + + private static final String JL_OBJECT_NAME = Object.class.getName(); + /** * Private methods which are not present in the original mapper interface and are added to map certain property * types. */ - private final Set usedVirtualMappings = new HashSet(); + private final Set usedSupportedMappings = new LinkedHashSet<>(); - public MappingResolverImpl(FormattingMessager messager, Elements elementUtils, Types typeUtils, + /** + * Private fields which are added to map certain property types. + */ + private final Set usedSupportedFields = new LinkedHashSet<>(); + + public MappingResolverImpl(FormattingMessager messager, ElementUtils elementUtils, TypeUtils typeUtils, TypeFactory typeFactory, List sourceModel, - List mapperReferences) { + List mapperReferences, boolean verboseLogging) { this.messager = messager; this.typeUtils = typeUtils; this.typeFactory = typeFactory; @@ -98,33 +114,45 @@ public MappingResolverImpl(FormattingMessager messager, Elements elementUtils, T this.sourceModel = sourceModel; this.mapperReferences = mapperReferences; - this.conversions = new Conversions( elementUtils, typeFactory ); + this.conversions = new Conversions( typeFactory ); this.builtInMethods = new BuiltInMappingMethods( typeFactory ); - this.methodSelectors = new MethodSelectors( typeUtils, elementUtils, typeFactory ); + this.methodSelectors = new MethodSelectors( typeUtils, elementUtils, messager, null ); + + this.verboseLogging = verboseLogging; } @Override - public Assignment getTargetAssignment(Method mappingMethod, Type targetType, String targetPropertyName, - FormattingParameters formattingParameters, SelectionParameters selectionParameters, SourceRHS sourceRHS, - boolean preferUpdateMapping) { - - SelectionCriteria criteria = - SelectionCriteria.forMappingMethods( selectionParameters, targetPropertyName, preferUpdateMapping ); + public Assignment getTargetAssignment(Method mappingMethod, ForgedMethodHistory description, Type targetType, + FormattingParameters formattingParameters, + SelectionCriteria criteria, SourceRHS sourceRHS, + AnnotationMirror positionHint, + Supplier forger) { ResolvingAttempt attempt = new ResolvingAttempt( sourceModel, mappingMethod, + description, formattingParameters, sourceRHS, - criteria + criteria, + positionHint, + forger, + builtInMethods.getBuiltInMethods(), + messager, + verboseLogging ); return attempt.getTargetAssignment( sourceRHS.getSourceTypeForMatching(), targetType ); } @Override - public Set getUsedVirtualMappings() { - return usedVirtualMappings; + public Set getUsedSupportedMappings() { + return usedSupportedMappings; + } + + @Override + public Set getUsedSupportedFields() { + return usedSupportedFields; } private MapperReference findMapperReference(Method method) { @@ -141,34 +169,51 @@ private MapperReference findMapperReference(Method method) { private class ResolvingAttempt { private final Method mappingMethod; + private final ForgedMethodHistory description; private final List methods; private final SelectionCriteria selectionCriteria; private final SourceRHS sourceRHS; - private final boolean savedPreferUpdateMapping; private final FormattingParameters formattingParameters; - - // resolving via 2 steps creates the possibillity of wrong matches, first builtin method matches, - // second doesn't. In that case, the first builtin method should not lead to a virtual method + private final AnnotationMirror positionHint; + private final Supplier forger; + private final List builtIns; + private final FormattingMessager messager; + private final int reportingLimitAmbiguous; + + // resolving via 2 steps creates the possibility of wrong matches, first builtin method matches, + // second doesn't. In that case, the first builtin method should not lead to a supported method // so this set must be cleared. - private final Set virtualMethodCandidates; + private final Set supportingMethodCandidates; - private ResolvingAttempt(List sourceModel, Method mappingMethod, - FormattingParameters formattingParameters, SourceRHS sourceRHS, SelectionCriteria criteria) { + // CHECKSTYLE:OFF + private ResolvingAttempt(List sourceModel, Method mappingMethod, ForgedMethodHistory description, + FormattingParameters formattingParameters, SourceRHS sourceRHS, + SelectionCriteria criteria, + AnnotationMirror positionHint, + Supplier forger, + List builtIns, + FormattingMessager messager, boolean verboseLogging) { this.mappingMethod = mappingMethod; - this.methods = filterPossibleCandidateMethods( sourceModel ); + this.description = description; this.formattingParameters = formattingParameters == null ? FormattingParameters.EMPTY : formattingParameters; this.sourceRHS = sourceRHS; - this.virtualMethodCandidates = new HashSet(); + this.supportingMethodCandidates = new LinkedHashSet<>(); this.selectionCriteria = criteria; - this.savedPreferUpdateMapping = criteria.isPreferUpdateMapping(); + this.positionHint = positionHint; + this.forger = forger; + this.builtIns = builtIns; + this.messager = messager; + this.reportingLimitAmbiguous = verboseLogging ? Integer.MAX_VALUE : LIMIT_REPORTING_AMBIGUOUS; + this.methods = filterPossibleCandidateMethods( sourceModel, mappingMethod ); } + // CHECKSTYLE:ON - private List filterPossibleCandidateMethods(List candidateMethods) { - List result = new ArrayList( candidateMethods.size() ); + private List filterPossibleCandidateMethods(List candidateMethods, T mappingMethod) { + List result = new ArrayList<>( candidateMethods.size() ); for ( T candidate : candidateMethods ) { - if ( isCandidateForMapping( candidate ) ) { + if ( isCandidateForMapping( candidate ) && isNotSelfOrSelfAllowed( mappingMethod, candidate ) ) { result.add( candidate ); } } @@ -176,22 +221,34 @@ private List filterPossibleCandidateMethods(List candid return result; } + private boolean isNotSelfOrSelfAllowed(T mappingMethod, T candidate) { + return selectionCriteria == null || selectionCriteria.isSelfAllowed() || !candidate.equals( mappingMethod ); + } + private Assignment getTargetAssignment(Type sourceType, Type targetType) { + Assignment assignment; + // first simple mapping method - Assignment referencedMethod = resolveViaMethod( sourceType, targetType, false ); - if ( referencedMethod != null ) { - referencedMethod.setAssignment( sourceRHS ); - return referencedMethod; + if ( allowMappingMethod() ) { + List> matches = getBestMatch( methods, sourceType, targetType ); + reportErrorWhenAmbiguous( matches, targetType ); + if ( !matches.isEmpty() ) { + assignment = toMethodRef( first( matches ) ); + assignment.setAssignment( sourceRHS ); + return assignment; + } } // then direct assignable - if ( sourceType.isAssignableTo( targetType ) || - isAssignableThroughCollectionCopyConstructor( sourceType, targetType ) ) { - Assignment simpleAssignment = sourceRHS; - return simpleAssignment; + if ( !hasQualfiers() ) { + if ( ( sourceType.isAssignableTo( targetType ) || + isAssignableThroughCollectionCopyConstructor( sourceType, targetType ) ) + && allowDirect( sourceType, targetType ) ) { + Assignment simpleAssignment = sourceRHS; + return simpleAssignment; + } } - // At this point the SourceType will either // 1. be a String // 2. or when its a primitive / wrapped type and analysis successful equal to its TargetType. But in that @@ -200,245 +257,222 @@ private Assignment getTargetAssignment(Type sourceType, Type targetType) { // in NativeType is not successful. We don't want to go through type conversion, double mappings etc. // with something that we already know to be wrong. if ( sourceType.isLiteral() - && "java.lang.String".equals( sourceType.getFullyQualifiedName( ) ) + && "java.lang.String".equals( sourceType.getFullyQualifiedName() ) && targetType.isNative() ) { - // TODO: convey some error message return null; } // then type conversion - Assignment conversion = resolveViaConversion( sourceType, targetType ); - if ( conversion != null ) { - conversion.setAssignment( sourceRHS ); - return conversion; - } + if ( allowConversion() ) { + if ( !hasQualfiers() ) { + ConversionAssignment conversion = resolveViaConversion( sourceType, targetType ); + if ( conversion != null ) { + conversion.reportMessageWhenNarrowing( messager, this ); + conversion.getAssignment().setAssignment( sourceRHS ); + return conversion.getAssignment(); + } + } - // check for a built-in method - Assignment builtInMethod = resolveViaBuiltInMethod( sourceType, targetType ); - if ( builtInMethod != null ) { - builtInMethod.setAssignment( sourceRHS ); - usedVirtualMappings.addAll( virtualMethodCandidates ); - return builtInMethod; + // check for a built-in method + if ( !hasQualfiers() ) { + List> matches = getBestMatch( builtIns, sourceType, targetType ); + reportErrorWhenAmbiguous( matches, targetType ); + if ( !matches.isEmpty() ) { + assignment = toBuildInRef( first( matches ) ); + assignment.setAssignment( sourceRHS ); + usedSupportedMappings.addAll( supportingMethodCandidates ); + return assignment; + } + } } - // 2 step method, first: method(method(source)) - referencedMethod = resolveViaMethodAndMethod( sourceType, targetType ); - if ( referencedMethod != null ) { - usedVirtualMappings.addAll( virtualMethodCandidates ); - return referencedMethod; - } + if ( allow2Steps() ) { + // 2 step method, first: method(method(source)) + assignment = MethodMethod.getBestMatch( this, sourceType, targetType ); + if ( assignment != null ) { + usedSupportedMappings.addAll( supportingMethodCandidates ); + return assignment; + } - // 2 step method, then: method(conversion(source)) - referencedMethod = resolveViaConversionAndMethod( sourceType, targetType ); - if ( referencedMethod != null ) { - usedVirtualMappings.addAll( virtualMethodCandidates ); - return referencedMethod; - } + // 2 step method, then: method(conversion(source)) + if ( allowConversion() ) { + assignment = ConversionMethod.getBestMatch( this, sourceType, targetType ); + if ( assignment != null ) { + usedSupportedMappings.addAll( supportingMethodCandidates ); + return assignment; + } + } - // stop here when looking for update methods. - selectionCriteria.setPreferUpdateMapping( false ); + // stop here when looking for update methods. + selectionCriteria.setPreferUpdateMapping( false ); - // 2 step method, finally: conversion(method(source)) - conversion = resolveViaMethodAndConversion( sourceType, targetType ); - if ( conversion != null ) { - usedVirtualMappings.addAll( virtualMethodCandidates ); - return conversion; + // 2 step method, finally: conversion(method(source)) + if ( allowConversion() ) { + assignment = MethodConversion.getBestMatch( this, sourceType, targetType ); + if ( assignment != null ) { + usedSupportedMappings.addAll( supportingMethodCandidates ); + return assignment; + } + } + } + + if ( hasQualfiers() ) { + if ( (sourceType.isCollectionType() || sourceType.isArrayType()) && targetType.isIterableType() ) { + // Allow forging iterable mapping when no iterable mapping already found + return forger.get(); + } + else { + printQualifierMessage( selectionCriteria ); + } + } + else if ( allowMappingMethod() ) { + // only forge if we would allow mapping method + return forger.get(); } // if nothing works, alas, the result is null return null; } - private Assignment resolveViaConversion(Type sourceType, Type targetType) { - ConversionProvider conversionProvider = conversions.getConversion( sourceType, targetType ); + private boolean hasQualfiers() { + return selectionCriteria != null && selectionCriteria.hasQualfiers(); + } - if ( conversionProvider == null ) { - return null; + private void printQualifierMessage(SelectionCriteria selectionCriteria ) { + + List annotations = selectionCriteria.getQualifiers().stream() + .filter( DeclaredType.class::isInstance ) + .map( DeclaredType.class::cast ) + .map( DeclaredType::asElement ) + .map( Element::getSimpleName ) + .map( Name::toString ) + .map( a -> "@" + a ) + .collect( Collectors.toList() ); + List names = selectionCriteria.getQualifiedByNames(); + + if ( !annotations.isEmpty() && !names.isEmpty() ) { + messager.printMessage( + mappingMethod.getExecutable(), + positionHint, + Message.GENERAL_NO_QUALIFYING_METHOD_COMBINED, + Strings.join( names, MessageConstants.AND ), + Strings.join( annotations, MessageConstants.AND ) + ); } - ConversionContext ctx = new DefaultConversionContext( - typeFactory, - messager, - sourceType, - targetType, - formattingParameters - ); - - // add helper methods required in conversion - for ( HelperMethod helperMethod : conversionProvider.getRequiredHelperMethods( ctx ) ) { - usedVirtualMappings.add( new VirtualMappingMethod( helperMethod ) ); + else if ( !annotations.isEmpty() ) { + messager.printMessage( + mappingMethod.getExecutable(), + positionHint, + Message.GENERAL_NO_QUALIFYING_METHOD_ANNOTATION, + Strings.join( annotations, MessageConstants.AND ) + ); + } + else { + messager.printMessage( + mappingMethod.getExecutable(), + positionHint, + Message.GENERAL_NO_QUALIFYING_METHOD_NAMED, + Strings.join( names, MessageConstants.AND ) + ); } - return conversionProvider.to( ctx ); + } - /** - * Returns a reference to a method mapping the given source type to the given target type, if such a method - * exists. - */ - private Assignment resolveViaMethod(Type sourceType, Type targetType, boolean considerBuiltInMethods) { + private boolean allowDirect( Type sourceType, Type targetType ) { + if ( selectionCriteria != null && selectionCriteria.isAllowDirect() ) { + return true; + } - // first try to find a matching source method - SelectedMethod matchingSourceMethod = getBestMatch( methods, sourceType, targetType ); + return allowDirect( sourceType ) || allowDirect( targetType ); + } - if ( matchingSourceMethod != null ) { - return getMappingMethodReference( matchingSourceMethod, targetType ); + private boolean allowDirect(Type type) { + if ( type.isPrimitive() ) { + return true; } - if ( considerBuiltInMethods ) { - return resolveViaBuiltInMethod( sourceType, targetType ); + if ( type.isEnumType() ) { + return true; } - return null; - } + if ( type.isArrayType() ) { + return type.isJavaLangType() || type.getComponentType().isPrimitive(); + } - private Assignment resolveViaBuiltInMethod(Type sourceType, Type targetType) { - SelectedMethod matchingBuiltInMethod = - getBestMatch( builtInMethods.getBuiltInMethods(), sourceType, targetType ); + if ( type.isIterableOrStreamType() ) { + List typeParameters = type.getTypeParameters(); + // For iterable or stream direct mapping is enabled when: + // - The type is raw (no type parameters) + // - The type parameter is allowed + return typeParameters.isEmpty() || allowDirect( Collections.first( typeParameters ) ); + } - if ( matchingBuiltInMethod != null ) { - virtualMethodCandidates.add( new VirtualMappingMethod( matchingBuiltInMethod.getMethod() ) ); - ConversionContext ctx = new DefaultConversionContext( - typeFactory, - messager, - sourceType, - targetType, - formattingParameters - ); - Assignment methodReference = MethodReference.forBuiltInMethod( matchingBuiltInMethod.getMethod(), ctx ); - methodReference.setAssignment( sourceRHS ); - return methodReference; + if ( type.isMapType() ) { + List typeParameters = type.getTypeParameters(); + // For map type direct mapping is enabled when: + // - The type os raw (no type parameters + // - The key and value are direct assignable + return typeParameters.isEmpty() || + ( allowDirect( typeParameters.get( 0 ) ) && allowDirect( typeParameters.get( 1 ) ) ); } - return null; + return type.isJavaLangType(); } - /** - * Suppose mapping required from A to C and: - *
        - *
      • no direct referenced mapping method either built-in or referenced is available from A to C
      • - *
      • no conversion is available
      • - *
      • there is a method from A to B, methodX
      • - *
      • there is a method from B to C, methodY
      • - *
      - * then this method tries to resolve this combination and make a mapping methodY( methodX ( parameter ) ) - */ - private Assignment resolveViaMethodAndMethod(Type sourceType, Type targetType) { - - List methodYCandidates = new ArrayList( methods ); - methodYCandidates.addAll( builtInMethods.getBuiltInMethods() ); - - Assignment methodRefY = null; - - // Iterate over all source methods. Check if the return type matches with the parameter that we need. - // so assume we need a method from A to C we look for a methodX from A to B (all methods in the - // list form such a candidate). - // For each of the candidates, we need to look if there's a methodY, either - // sourceMethod or builtIn that fits the signature B to C. Only then there is a match. If we have a match - // a nested method call can be called. so C = methodY( methodX (A) ) - for ( Method methodYCandidate : methodYCandidates ) { - methodRefY = - resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(), targetType, true ); - - if ( methodRefY != null ) { - selectionCriteria.setPreferUpdateMapping( false ); - Assignment methodRefX = - resolveViaMethod( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType(), true ); - selectionCriteria.setPreferUpdateMapping( savedPreferUpdateMapping ); - if ( methodRefX != null ) { - methodRefY.setAssignment( methodRefX ); - methodRefX.setAssignment( sourceRHS ); - break; - } - else { - // both should match; - virtualMethodCandidates.clear(); - methodRefY = null; - } - } - } - return methodRefY; + private boolean allowConversion() { + return selectionCriteria != null && selectionCriteria.isAllowConversion(); } - /** - * Suppose mapping required from A to C and: - *
        - *
      • there is a conversion from A to B, conversionX
      • - *
      • there is a method from B to C, methodY
      • - *
      - * then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) ) - */ - private Assignment resolveViaConversionAndMethod(Type sourceType, Type targetType) { - - List methodYCandidates = new ArrayList( methods ); - methodYCandidates.addAll( builtInMethods.getBuiltInMethods() ); + private boolean allowMappingMethod() { + return selectionCriteria != null && selectionCriteria.isAllowMappingMethod(); + } - Assignment methodRefY = null; + private boolean allow2Steps() { + return selectionCriteria != null && selectionCriteria.isAllow2Steps(); + } - for ( Method methodYCandidate : methodYCandidates ) { - methodRefY = - resolveViaMethod( methodYCandidate.getSourceParameters().get( 0 ).getType(), targetType, true ); + private ConversionAssignment resolveViaConversion(Type sourceType, Type targetType) { - if ( methodRefY != null ) { - Assignment conversionXRef = - resolveViaConversion( sourceType, methodYCandidate.getSourceParameters().get( 0 ).getType() ); - if ( conversionXRef != null ) { - methodRefY.setAssignment( conversionXRef ); - conversionXRef.setAssignment( sourceRHS ); - break; - } - else { - // both should match - virtualMethodCandidates.clear(); - methodRefY = null; - } - } + ConversionProvider conversionProvider = conversions.getConversion( sourceType, targetType ); + if ( conversionProvider == null ) { + return null; } - return methodRefY; - } - - /** - * Suppose mapping required from A to C and: - *
        - *
      • there is a conversion from A to B, conversionX
      • - *
      • there is a method from B to C, methodY
      • - *
      - * then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) ) - */ - private Assignment resolveViaMethodAndConversion(Type sourceType, Type targetType) { + ConversionContext ctx = new DefaultConversionContext( + typeFactory, + messager, + sourceType, + targetType, + formattingParameters + ); - List methodXCandidates = new ArrayList( methods ); - methodXCandidates.addAll( builtInMethods.getBuiltInMethods() ); + // add helper methods required in conversion + Set allUsedFields = new HashSet<>( mapperReferences ); + SupportingField.addAllFieldsIn( supportingMethodCandidates, allUsedFields ); - Assignment conversionYRef = null; + for ( FieldReference helperField : conversionProvider.getRequiredHelperFields( ctx ) ) { + Field field = SupportingField.getSafeField( null, helperField, allUsedFields ); + allUsedFields.add( field ); + usedSupportedFields.add( field ); + } - // search the other way around - for ( Method methodXCandidate : methodXCandidates ) { - if ( methodXCandidate.getMappingTargetParameter() != null ) { - continue; - } + for ( HelperMethod helperMethod : conversionProvider.getRequiredHelperMethods( ctx ) ) { + SupportingMappingMethod supportingMappingMethod = + new SupportingMappingMethod( helperMethod ); + SupportingField.addAllFieldsIn( Collections.asSet( supportingMappingMethod ), allUsedFields ); + usedSupportedMappings.add( supportingMappingMethod ); + } - Assignment methodRefX = resolveViaMethod( - sourceType, - methodXCandidate.getReturnType(), - true - ); - if ( methodRefX != null ) { - conversionYRef = resolveViaConversion( methodXCandidate.getReturnType(), targetType ); - if ( conversionYRef != null ) { - conversionYRef.setAssignment( methodRefX ); - methodRefX.setAssignment( sourceRHS ); - break; - } - else { - // both should match; - virtualMethodCandidates.clear(); - conversionYRef = null; - } - } + Assignment conversion = conversionProvider.to( ctx ); + if ( conversion != null ) { + return new ConversionAssignment( sourceType, targetType, conversion ); } - return conversionYRef; + return null; } private boolean isCandidateForMapping(Method methodCandidate) { + if ( methodCandidate.getConditionOptions().isAnyStrategyApplicable() ) { + return false; + } return isCreateMethodForMapping( methodCandidate ) || isUpdateMethodForMapping( methodCandidate ); } @@ -457,52 +491,75 @@ private boolean isUpdateMethodForMapping(Method methodCandidate) { && !methodCandidate.isLifecycleCallbackMethod(); } - private SelectedMethod getBestMatch(List methods, Type sourceType, Type returnType) { - - List> candidates = methodSelectors.getMatchingMethods( - mappingMethod, + private List> getBestMatch(List methods, Type source, Type target) { + return methodSelectors.getMatchingMethods( methods, - singletonList( sourceType ), - returnType, - selectionCriteria + SelectionContext.forMappingMethods( mappingMethod, source, target, selectionCriteria, typeFactory ) ); + } + + private void reportErrorWhenAmbiguous(List> candidates, Type target) { // raise an error if more than one mapping method is suitable to map the given source type // into the target type if ( candidates.size() > 1 ) { + String descriptionStr = ""; + if ( description != null ) { + descriptionStr = description.createSourcePropertyErrorMessage(); + } + else { + descriptionStr = sourceRHS.getSourceErrorMessagePart(); + } + if ( sourceRHS.getSourceErrorMessagePart() != null ) { - messager.printMessage( mappingMethod.getExecutable(), - Message.GENERAL_AMBIGIOUS_MAPPING_METHOD, - sourceRHS.getSourceErrorMessagePart(), - returnType, - Strings.join( candidates, ", " ) + messager.printMessage( + mappingMethod.getExecutable(), + positionHint, + Message.GENERAL_AMBIGUOUS_MAPPING_METHOD, + descriptionStr, + target.describe(), + join( candidates ) ); } else { - messager.printMessage( mappingMethod.getExecutable(), - Message.GENERAL_AMBIGIOUS_FACTORY_METHOD, - returnType, - Strings.join( candidates, ", " ) + messager.printMessage( + mappingMethod.getExecutable(), + positionHint, + Message.GENERAL_AMBIGUOUS_FACTORY_METHOD, + target.describe(), + join( candidates ) ); } } - - if ( !candidates.isEmpty() ) { - return first( candidates ); - } - - return null; } - private Assignment getMappingMethodReference(SelectedMethod method, - Type targetType) { - MapperReference mapperReference = findMapperReference( method.getMethod() ); + private Assignment toMethodRef(SelectedMethod selectedMethod) { + MapperReference mapperReference = findMapperReference( selectedMethod.getMethod() ); return MethodReference.forMapperReference( - method.getMethod(), + selectedMethod.getMethod(), mapperReference, - method.getParameterBindings() ); + selectedMethod.getParameterBindings() + ); + } + + private Assignment toBuildInRef(SelectedMethod selectedMethod) { + BuiltInMethod method = selectedMethod.getMethod(); + Set allUsedFields = new HashSet<>( mapperReferences ); + SupportingField.addAllFieldsIn( supportingMethodCandidates, allUsedFields ); + SupportingMappingMethod supportingMappingMethod = new SupportingMappingMethod( method, allUsedFields ); + supportingMethodCandidates.add( supportingMappingMethod ); + ConversionContext ctx = new DefaultConversionContext( + typeFactory, + messager, + method.getMappingSourceType(), + method.getResultType(), + formattingParameters + ); + Assignment methodReference = MethodReference.forBuiltInMethod( method, ctx ); + methodReference.setAssignment( sourceRHS ); + return methodReference; } /** @@ -513,14 +570,14 @@ private boolean isAssignableThroughCollectionCopyConstructor(Type sourceType, Ty boolean bothCollectionOrMap = false; if ( ( sourceType.isCollectionType() && targetType.isCollectionType() ) || - ( sourceType.isMapType() && targetType.isMapType() ) ) { + ( sourceType.isMapType() && targetType.isMapType() ) ) { bothCollectionOrMap = true; } if ( bothCollectionOrMap ) { return hasCompatibleCopyConstructor( - sourceType, - targetType.getImplementationType() != null ? targetType.getImplementationType() : targetType + sourceType, + targetType.getImplementationType() != null ? targetType.getImplementationType() : targetType ); } @@ -532,8 +589,9 @@ private boolean isAssignableThroughCollectionCopyConstructor(Type sourceType, Ty * * @param sourceType the source type * @param targetType the target type + * * @return {@code true} if the target type has a constructor accepting the given source type, {@code false} - * otherwise. + * otherwise. */ private boolean hasCompatibleCopyConstructor(Type sourceType, Type targetType) { if ( targetType.isPrimitive() ) { @@ -551,7 +609,8 @@ private boolean hasCompatibleCopyConstructor(Type sourceType, Type targetType) { // get the constructor resolved against the type arguments of specific target type ExecutableType typedConstructor = (ExecutableType) typeUtils.asMemberOf( (DeclaredType) targetType.getTypeMirror(), - constructor ); + constructor + ); TypeMirror parameterType = Collections.first( typedConstructor.getParameterTypes() ); if ( parameterType.getKind() == TypeKind.DECLARED ) { @@ -563,14 +622,15 @@ private boolean hasCompatibleCopyConstructor(Type sourceType, Type targetType) { // handled in SpecificCompilerWorkarounds... DeclaredType p = (DeclaredType) parameterType; - List typeArguments = new ArrayList( p.getTypeArguments().size() ); + List typeArguments = new ArrayList<>( p.getTypeArguments().size() ); for ( TypeMirror tArg : p.getTypeArguments() ) { typeArguments.add( typeFactory.getTypeBound( tArg ) ); } parameterType = typeUtils.getDeclaredType( (TypeElement) p.asElement(), - typeArguments.toArray( new TypeMirror[typeArguments.size()] ) ); + typeArguments.toArray( new TypeMirror[typeArguments.size()] ) + ); } if ( typeUtils.isAssignable( sourceType.getTypeMirror(), parameterType ) ) { @@ -580,5 +640,506 @@ private boolean hasCompatibleCopyConstructor(Type sourceType, Type targetType) { return false; } + + private String join( List> candidates ) { + + String candidateStr = candidates.stream() + .limit( reportingLimitAmbiguous ) + .map( m -> m.getMethod().describe() ) + .collect( Collectors.joining( ", " ) ); + + if ( candidates.size() > reportingLimitAmbiguous ) { + candidateStr += String.format( "... and %s more", candidates.size() - reportingLimitAmbiguous ); + } + return candidateStr; + } } + + private static class ConversionAssignment { + + private final Type sourceType; + private final Type targetType; + private final Assignment assignment; + + ConversionAssignment(Type sourceType, Type targetType, Assignment assignment) { + this.sourceType = sourceType; + this.targetType = targetType; + this.assignment = assignment; + } + + Assignment getAssignment() { + return assignment; + } + + void reportMessageWhenNarrowing(FormattingMessager messager, ResolvingAttempt attempt) { + + Type source = sourceType; + if ( sourceType.isOptionalType() ) { + source = sourceType.getOptionalBaseType(); + } + + Type target = targetType; + if ( targetType.isOptionalType() ) { + target = targetType.getOptionalBaseType(); + } + if ( NativeTypes.isNarrowing( source.getFullyQualifiedName(), target.getFullyQualifiedName() ) ) { + ReportingPolicyGem policy = attempt.mappingMethod.getOptions().getMapper().typeConversionPolicy(); + if ( policy == ReportingPolicyGem.WARN ) { + report( messager, attempt, Message.CONVERSION_LOSSY_WARNING ); + } + else if ( policy == ReportingPolicyGem.ERROR ) { + report( messager, attempt, Message.CONVERSION_LOSSY_ERROR ); + } + } + } + + private void report(FormattingMessager messager, ResolvingAttempt attempt, Message message) { + + messager.printMessage( + attempt.mappingMethod.getExecutable(), + attempt.positionHint, + message, + attempt.sourceRHS.getSourceErrorMessagePart(), + sourceType.describe(), + targetType.describe() + ); + } + + String shortName() { + return sourceType.getName() + "-->" + targetType.getName(); + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + ConversionAssignment that = (ConversionAssignment) o; + return sourceType.equals( that.sourceType ) && targetType.equals( that.targetType ); + } + + @Override + public int hashCode() { + return Objects.hash( sourceType, targetType ); + } + } + + private enum BestMatchType { + IGNORE_QUALIFIERS_BEFORE_Y_CANDIDATES, + IGNORE_QUALIFIERS_AFTER_Y_CANDIDATES, + } + + /** + * Suppose mapping required from A to C and: + *
        + *
      • no direct referenced mapping method either built-in or referenced is available from A to C
      • + *
      • no conversion is available
      • + *
      • there is a method from A to B, methodX
      • + *
      • there is a method from B to C, methodY
      • + *
      + * then this method tries to resolve this combination and make a mapping methodY( methodX ( parameter ) ) + * + * NOTE method X cannot be an update method + */ + private static class MethodMethod { + + private final ResolvingAttempt attempt; + private final List xMethods; + private final List yMethods; + private final Function, Assignment> xCreate; + private final Function, Assignment> yCreate; + + // results + private boolean hasResult = false; + private Assignment result = null; + + static Assignment getBestMatch(ResolvingAttempt att, Type sourceType, Type targetType) { + MethodMethod mmAttempt = + new MethodMethod<>( att, att.methods, att.methods, att::toMethodRef, att::toMethodRef ) + .getBestMatch( sourceType, targetType ); + if ( mmAttempt.hasResult ) { + return mmAttempt.result; + } + if ( att.hasQualfiers() ) { + mmAttempt = mmAttempt.getBestMatchIgnoringQualifiersBeforeY( sourceType, targetType ); + if ( mmAttempt.hasResult ) { + return mmAttempt.result; + } + + mmAttempt = mmAttempt.getBestMatchIgnoringQualifiersAfterY( sourceType, targetType ); + if ( mmAttempt.hasResult ) { + return mmAttempt.result; + } + } + if ( att.allowConversion() ) { + MethodMethod mbAttempt = + new MethodMethod<>( att, att.methods, att.builtIns, att::toMethodRef, att::toBuildInRef ) + .getBestMatch( sourceType, targetType ); + if ( mbAttempt.hasResult ) { + return mbAttempt.result; + } + MethodMethod bmAttempt = + new MethodMethod<>( att, att.builtIns, att.methods, att::toBuildInRef, att::toMethodRef ) + .getBestMatch( sourceType, targetType ); + if ( bmAttempt.hasResult ) { + return bmAttempt.result; + } + MethodMethod bbAttempt = + new MethodMethod<>( att, att.builtIns, att.builtIns, att::toBuildInRef, att::toBuildInRef ) + .getBestMatch( sourceType, targetType ); + return bbAttempt.result; + } + + return null; + } + + MethodMethod(ResolvingAttempt attempt, List xMethods, List yMethods, + Function, Assignment> xCreate, + Function, Assignment> yCreate) { + this.attempt = attempt; + this.xMethods = xMethods; + this.yMethods = yMethods; + this.xCreate = xCreate; + this.yCreate = yCreate; + } + + private MethodMethod getBestMatch(Type sourceType, Type targetType) { + return getBestMatch( sourceType, targetType, null ); + } + + private MethodMethod getBestMatchIgnoringQualifiersBeforeY(Type sourceType, Type targetType) { + return getBestMatch( sourceType, targetType, BestMatchType.IGNORE_QUALIFIERS_BEFORE_Y_CANDIDATES ); + } + + private MethodMethod getBestMatchIgnoringQualifiersAfterY(Type sourceType, Type targetType) { + return getBestMatch( sourceType, targetType, BestMatchType.IGNORE_QUALIFIERS_AFTER_Y_CANDIDATES ); + } + + private MethodMethod getBestMatch(Type sourceType, Type targetType, BestMatchType matchType) { + + Set yCandidates = new HashSet<>(); + Map, List>> xCandidates = new LinkedHashMap<>(); + Map, Type> typesInTheMiddle = new LinkedHashMap<>(); + + // Iterate over all source methods. Check if the return type matches with the parameter that we need. + // so assume we need a method from A to C we look for a methodX from A to B (all methods in the + // list form such a candidate). + // For each of the candidates, we need to look if there's a methodY, either + // sourceMethod or builtIn that fits the signature B to C. Only then there is a match. If we have a match + // a nested method call can be called. so C = methodY( methodX (A) ) + attempt.selectionCriteria.setPreferUpdateMapping( false ); + attempt.selectionCriteria.setIgnoreQualifiers( + matchType == BestMatchType.IGNORE_QUALIFIERS_BEFORE_Y_CANDIDATES ); + + for ( T2 yCandidate : yMethods ) { + Type ySourceType = yCandidate.getMappingSourceType(); + ySourceType = ySourceType.resolveGenericTypeParameters( targetType, yCandidate.getResultType() ); + Type yTargetType = yCandidate.getResultType(); + if ( ySourceType == null + || !yTargetType.isRawAssignableTo( targetType ) + || JL_OBJECT_NAME.equals( ySourceType.getFullyQualifiedName() ) ) { + // java.lang.Object as intermediate result + continue; + } + List> xMatches = attempt.getBestMatch( xMethods, sourceType, ySourceType ); + if ( !xMatches.isEmpty() ) { + for ( SelectedMethod x : xMatches ) { + xCandidates.put( x, new ArrayList<>() ); + typesInTheMiddle.put( x, ySourceType ); + } + yCandidates.add( yCandidate ); + } + } + attempt.selectionCriteria.setPreferUpdateMapping( true ); + attempt.selectionCriteria.setIgnoreQualifiers( + matchType == BestMatchType.IGNORE_QUALIFIERS_AFTER_Y_CANDIDATES ); + + // collect all results + List yCandidatesList = new ArrayList<>( yCandidates ); + Iterator, List>>> i = xCandidates.entrySet().iterator(); + while ( i.hasNext() ) { + Map.Entry, List>> entry = i.next(); + Type typeInTheMiddle = typesInTheMiddle.get( entry.getKey() ); + entry.getValue().addAll( attempt.getBestMatch( yCandidatesList, typeInTheMiddle, targetType ) ); + if ( entry.getValue().isEmpty() ) { + i.remove(); + } + } + + attempt.selectionCriteria.setIgnoreQualifiers( false ); + // no results left + if ( xCandidates.isEmpty() ) { + return this; + } + hasResult = true; + + // get result, there should be one entry left with only one value + if ( xCandidates.size() == 1 && firstValue( xCandidates ).size() == 1 ) { + Assignment methodRefY = yCreate.apply( first( firstValue( xCandidates ) ) ); + Assignment methodRefX = xCreate.apply( firstKey( xCandidates ) ); + methodRefY.setAssignment( methodRefX ); + methodRefX.setAssignment( attempt.sourceRHS ); + result = methodRefY; + } + else { + reportAmbiguousError( xCandidates, targetType ); + } + return this; + + } + + void reportAmbiguousError(Map, List>> xCandidates, Type target) { + StringBuilder result = new StringBuilder(); + xCandidates.entrySet() + .stream() + .limit( attempt.reportingLimitAmbiguous ) + .forEach( e -> result.append( "method(s)Y: " ) + .append( attempt.join( e.getValue() ) ) + .append( ", methodX: " ) + .append( e.getKey().getMethod().describe() ) + .append( "; " ) ); + attempt.messager.printMessage( + attempt.mappingMethod.getExecutable(), + attempt.positionHint, + Message.GENERAL_AMBIGUOUS_MAPPING_METHODY_METHODX, + attempt.sourceRHS.getSourceType().getName() + " " + attempt.sourceRHS.getSourceParameterName(), + target.getName(), + result.toString() ); + } + } + + /** + * Suppose mapping required from A to C and: + *
        + *
      • there is a conversion from A to B, conversionX
      • + *
      • there is a method from B to C, methodY
      • + *
      + * then this method tries to resolve this combination and make a mapping methodY( conversionX ( parameter ) ) + * + * Instead of directly using a built in method candidate, all the return types as 'B' of all available built-in + * methods are used to resolve a mapping (assignment) from result type to 'B'. If a match is found, an attempt + * is done to find a matching type conversion. + */ + private static class ConversionMethod { + + private final ResolvingAttempt attempt; + private final List methods; + private final Function, Assignment> create; + + // results + private boolean hasResult = false; + private Assignment result = null; + + static Assignment getBestMatch(ResolvingAttempt att, Type sourceType, Type targetType) { + ConversionMethod mAttempt = new ConversionMethod<>( att, att.methods, att::toMethodRef ) + .getBestMatch( sourceType, targetType ); + if ( mAttempt.hasResult ) { + return mAttempt.result; + } + ConversionMethod bAttempt = + new ConversionMethod<>( att, att.builtIns, att::toBuildInRef ) + .getBestMatch( sourceType, targetType ); + return bAttempt.result; + } + + ConversionMethod(ResolvingAttempt attempt, List methods, Function, Assignment> create) { + this.attempt = attempt; + this.methods = methods; + this.create = create; + } + + private ConversionMethod getBestMatch(Type sourceType, Type targetType) { + + List yCandidates = new ArrayList<>(); + Map>> xRefCandidates = new LinkedHashMap<>(); + + for ( T yCandidate : methods ) { + Type ySourceType = yCandidate.getMappingSourceType(); + ySourceType = ySourceType.resolveParameterToType( targetType, yCandidate.getResultType() ).getMatch(); + Type yTargetType = yCandidate.getResultType(); + if ( ySourceType == null + || !yTargetType.isRawAssignableTo( targetType ) + || JL_OBJECT_NAME.equals( ySourceType.getFullyQualifiedName() ) ) { + // java.lang.Object as intermediate result + continue; + } + ConversionAssignment xRefCandidate = attempt.resolveViaConversion( sourceType, ySourceType ); + if ( xRefCandidate != null ) { + xRefCandidates.put( xRefCandidate, new ArrayList<>() ); + yCandidates.add( yCandidate ); + } + } + + // collect all results + Iterator>>> i = xRefCandidates.entrySet().iterator(); + while ( i.hasNext() ) { + Map.Entry>> entry = i.next(); + entry.getValue().addAll( attempt.getBestMatch( yCandidates, entry.getKey().targetType, targetType ) ); + if ( entry.getValue().isEmpty() ) { + i.remove(); + } + } + + // no results left + if ( xRefCandidates.isEmpty() ) { + return this; + } + hasResult = true; + + // get result, there should be one entry left with only one value + if ( xRefCandidates.size() == 1 && firstValue( xRefCandidates ).size() == 1 ) { + Assignment methodRefY = create.apply( first( firstValue( xRefCandidates ) ) ); + ConversionAssignment conversionRefX = firstKey( xRefCandidates ); + conversionRefX.reportMessageWhenNarrowing( attempt.messager, attempt ); + methodRefY.setAssignment( conversionRefX.assignment ); + conversionRefX.assignment.setAssignment( attempt.sourceRHS ); + result = methodRefY; + } + else { + reportAmbiguousError( xRefCandidates, targetType ); + } + return this; + + } + + void reportAmbiguousError(Map>> xRefCandidates, Type target) { + StringBuilder result = new StringBuilder(); + xRefCandidates.entrySet() + .stream() + .limit( attempt.reportingLimitAmbiguous ) + .forEach( e -> result.append( "method(s)Y: " ) + .append( attempt.join( e.getValue() ) ) + .append( ", conversionX: " ) + .append( e.getKey().shortName() ) + .append( "; " ) ); + attempt.messager.printMessage( + attempt.mappingMethod.getExecutable(), + attempt.positionHint, + Message.GENERAL_AMBIGUOUS_MAPPING_METHODY_CONVERSIONX, + attempt.sourceRHS.getSourceType().getName() + " " + attempt.sourceRHS.getSourceParameterName(), + target.getName(), + result.toString() ); + } + } + + /** + * Suppose mapping required from A to C and: + *
        + *
      • there is a method from A to B, methodX
      • + *
      • there is a conversion from B to C, conversionY
      • + *
      + * then this method tries to resolve this combination and make a mapping conversionY( methodX ( parameter ) ) + * + * Instead of directly using a built in method candidate, all the return types as 'B' of all available built-in + * methods are used to resolve a mapping (assignment) from source type to 'B'. If a match is found, an attempt + * is done to find a matching type conversion. + * + * NOTE methodX cannot be an update method + */ + private static class MethodConversion { + + private final ResolvingAttempt attempt; + private final List methods; + private final Function, Assignment> create; + + // results + private boolean hasResult = false; + private Assignment result = null; + + static Assignment getBestMatch(ResolvingAttempt att, Type sourceType, Type targetType) { + MethodConversion mAttempt = new MethodConversion<>( att, att.methods, att::toMethodRef ) + .getBestMatch( sourceType, targetType ); + if ( mAttempt.hasResult ) { + return mAttempt.result; + } + MethodConversion bAttempt = new MethodConversion<>( att, att.builtIns, att::toBuildInRef ) + .getBestMatch( sourceType, targetType ); + return bAttempt.result; + } + + MethodConversion(ResolvingAttempt attempt, List methods, Function, Assignment> create) { + this.attempt = attempt; + this.methods = methods; + this.create = create; + } + + private MethodConversion getBestMatch(Type sourceType, Type targetType) { + + List xCandidates = new ArrayList<>(); + Map>> yRefCandidates = new LinkedHashMap<>(); + + // search through methods, and select egible candidates + for ( T xCandidate : methods ) { + Type xTargetType = xCandidate.getReturnType(); + Type xSourceType = xCandidate.getMappingSourceType(); + xTargetType = xTargetType.resolveParameterToType( sourceType, xSourceType ).getMatch(); + if ( xTargetType == null + || xCandidate.isUpdateMethod() + || !sourceType.isRawAssignableTo( xSourceType ) + || JL_OBJECT_NAME.equals( xTargetType.getFullyQualifiedName() ) ) { + // skip update methods || java.lang.Object as intermediate result + continue; + } + ConversionAssignment yRefCandidate = attempt.resolveViaConversion( xTargetType, targetType ); + if ( yRefCandidate != null ) { + yRefCandidates.put( yRefCandidate, new ArrayList<>() ); + xCandidates.add( xCandidate ); + } + } + + // collect all results + Iterator>>> i = yRefCandidates.entrySet().iterator(); + while ( i.hasNext() ) { + Map.Entry>> entry = i.next(); + entry.getValue().addAll( attempt.getBestMatch( xCandidates, sourceType, entry.getKey().sourceType ) ); + if ( entry.getValue().isEmpty() ) { + i.remove(); + } + } + + // no results left + if ( yRefCandidates.isEmpty() ) { + return this; + } + hasResult = true; + + // get result, there should be one entry left with only one value + if ( yRefCandidates.size() == 1 && firstValue( yRefCandidates ).size() == 1 ) { + Assignment methodRefX = create.apply( first( firstValue( yRefCandidates ) ) ); + ConversionAssignment conversionRefY = firstKey( yRefCandidates ); + conversionRefY.reportMessageWhenNarrowing( attempt.messager, attempt ); + methodRefX.setAssignment( attempt.sourceRHS ); + conversionRefY.assignment.setAssignment( methodRefX ); + result = conversionRefY.assignment; + } + else { + reportAmbiguousError( yRefCandidates, targetType ); + } + return this; + + } + + void reportAmbiguousError(Map>> yRefCandidates, Type target) { + StringBuilder result = new StringBuilder(); + yRefCandidates.entrySet() + .stream() + .limit( attempt.reportingLimitAmbiguous ) + .forEach( e -> result.append( "conversionY: " ) + .append( e.getKey().shortName() ) + .append( ", method(s)X: " ) + .append( attempt.join( e.getValue() ) ) + .append( "; " ) ); + attempt.messager.printMessage( + attempt.mappingMethod.getExecutable(), + attempt.positionHint, + Message.GENERAL_AMBIGUOUS_MAPPING_CONVERSIONY_METHODX, + attempt.sourceRHS.getSourceType().getName() + " " + attempt.sourceRHS.getSourceParameterName(), + target.getName(), + result.toString() ); + } + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/package-info.java index 794fec7503..d8ab59ad5a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/creation/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/processor/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/processor/package-info.java index 90503dafd8..b0aa0d0a16 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/processor/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/processor/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/AbstractElementUtilsDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/AbstractElementUtilsDecorator.java new file mode 100644 index 0000000000..67ce6e10ff --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/AbstractElementUtilsDecorator.java @@ -0,0 +1,331 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.AnnotationValue; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.ModuleElement; +import javax.lang.model.element.Name; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; + +import org.mapstruct.ap.spi.TypeHierarchyErroneousException; + +import static javax.lang.model.util.ElementFilter.fieldsIn; +import static javax.lang.model.util.ElementFilter.methodsIn; + +/** + * MapStruct specific abstract implementation of {@link ElementUtils}. + * This allows us to provide different implementations for different compilers and / or + * to allow us for easier implementation of using the module system. + */ +public abstract class AbstractElementUtilsDecorator implements ElementUtils { + + private final Elements delegate; + /** + * The module element when running with the module system, + * {@code null} otherwise. + */ + private final Element moduleElement; + + @IgnoreJRERequirement + AbstractElementUtilsDecorator(ProcessingEnvironment processingEnv, TypeElement mapperElement) { + this.delegate = processingEnv.getElementUtils(); + if ( SourceVersion.RELEASE_8.compareTo( processingEnv.getSourceVersion() ) >= 0 ) { + // We are running with Java 8 or lower + this.moduleElement = null; + } + else { + this.moduleElement = this.delegate.getModuleOf( mapperElement ); + } + } + + @Override + @IgnoreJRERequirement + public PackageElement getPackageElement(CharSequence name) { + if ( this.moduleElement == null ) { + return this.delegate.getPackageElement( name ); + } + + // If the module element is not null then we must be running on Java 8+ + return this.delegate.getPackageElement( (ModuleElement) moduleElement, name ); + } + + @Override + @IgnoreJRERequirement + public TypeElement getTypeElement(CharSequence name) { + if ( this.moduleElement == null ) { + return this.delegate.getTypeElement( name ); + } + + // If the module element is not null then we must be running on Java 8+ + return this.delegate.getTypeElement( (ModuleElement) moduleElement, name ); + } + + @Override + public Map getElementValuesWithDefaults( + AnnotationMirror a) { + return delegate.getElementValuesWithDefaults( a ); + } + + @Override + public String getDocComment(Element e) { + return delegate.getDocComment( e ); + } + + @Override + public boolean isDeprecated(Element e) { + return delegate.isDeprecated( e ); + } + + @Override + public Name getBinaryName(TypeElement type) { + return delegate.getBinaryName( type ); + } + + @Override + public PackageElement getPackageOf(Element type) { + return delegate.getPackageOf( type ); + } + + @Override + public List getAllMembers(TypeElement type) { + return delegate.getAllMembers( type ); + } + + @Override + public List getAllAnnotationMirrors(Element e) { + return delegate.getAllAnnotationMirrors( e ); + } + + @Override + public boolean hides(Element hider, Element hidden) { + return delegate.hides( hider, hidden ); + } + + @Override + public boolean overrides(ExecutableElement overrider, ExecutableElement overridden, TypeElement type) { + return delegate.overrides( overrider, overridden, type ); + } + + @Override + public String getConstantExpression(Object value) { + return delegate.getConstantExpression( value ); + } + + @Override + public void printElements(Writer w, Element... elements) { + delegate.printElements( w, elements ); + } + + @Override + public Name getName(CharSequence cs) { + return delegate.getName( cs ); + } + + @Override + public boolean isFunctionalInterface(TypeElement type) { + return delegate.isFunctionalInterface( type ); + } + + @Override + public List getAllEnclosedExecutableElements(TypeElement element) { + List enclosedElements = new ArrayList<>(); + element = replaceTypeElementIfNecessary( element ); + addEnclosedMethodsInHierarchy( enclosedElements, new HashSet<>(), element, element ); + + return enclosedElements; + } + + @Override + public List getAllEnclosedFields( TypeElement element) { + List enclosedElements = new ArrayList<>(); + element = replaceTypeElementIfNecessary( element ); + addEnclosedFieldsInHierarchy( enclosedElements, element, element ); + + return enclosedElements; + } + + private void addEnclosedMethodsInHierarchy(List alreadyAdded, + Collection alreadyVisitedElements, + TypeElement element, + TypeElement parentType) { + if ( element != parentType ) { // otherwise the element was already checked for replacement + element = replaceTypeElementIfNecessary( element ); + } + + if ( element.asType().getKind() == TypeKind.ERROR ) { + throw new TypeHierarchyErroneousException( element ); + } + + if ( !alreadyVisitedElements.add( element.getQualifiedName().toString() ) ) { + // If we already visited the element we should not go into it again. + // This can happen when diamond inheritance is used with interfaces + return; + } + addMethodNotYetOverridden( alreadyAdded, methodsIn( element.getEnclosedElements() ), parentType ); + + if ( hasNonObjectSuperclass( element ) ) { + addEnclosedMethodsInHierarchy( + alreadyAdded, + alreadyVisitedElements, + asTypeElement( element.getSuperclass() ), + parentType + ); + } + + for ( TypeMirror interfaceType : element.getInterfaces() ) { + addEnclosedMethodsInHierarchy( + alreadyAdded, + alreadyVisitedElements, + asTypeElement( interfaceType ), + parentType + ); + } + + } + + /** + * @param alreadyCollected methods that have already been collected and to which the not-yet-overridden methods will + * be added + * @param methodsToAdd methods to add to alreadyAdded, if they are not yet overridden by an element in the list + * @param parentType the type for with elements are collected + */ + private void addMethodNotYetOverridden(List alreadyCollected, + List methodsToAdd, + TypeElement parentType) { + List safeToAdd = new ArrayList<>( methodsToAdd.size() ); + for ( ExecutableElement toAdd : methodsToAdd ) { + if ( isNotPrivate( toAdd ) && isNotObjectEquals( toAdd ) + && methodWasNotYetOverridden( alreadyCollected, toAdd, parentType ) ) { + safeToAdd.add( toAdd ); + } + } + + alreadyCollected.addAll( 0, safeToAdd ); + } + + /** + * @param executable the executable to check + * @return {@code true}, iff the executable does not represent {@link java.lang.Object#equals(Object)} or an + * overridden version of it + */ + private boolean isNotObjectEquals(ExecutableElement executable) { + if ( executable.getSimpleName().contentEquals( "equals" ) && executable.getParameters().size() == 1 + && asTypeElement( executable.getParameters().get( 0 ).asType() ).getQualifiedName().contentEquals( + "java.lang.Object" + ) ) { + return false; + } + return true; + } + + /** + * @param alreadyCollected the list of already collected methods of one type hierarchy (order is from sub-types to + * super-types) + * @param executable the method to check + * @param parentType the type for which elements are collected + * @return {@code true}, iff the given executable was not yet overridden by a method in the given list. + */ + private boolean methodWasNotYetOverridden(List alreadyCollected, + ExecutableElement executable, TypeElement parentType) { + for ( ListIterator it = alreadyCollected.listIterator(); it.hasNext(); ) { + ExecutableElement executableInSubtype = it.next(); + if ( executableInSubtype == null ) { + continue; + } + if ( delegate.overrides( executableInSubtype, executable, parentType ) ) { + return false; + } + else if ( delegate.overrides( executable, executableInSubtype, parentType ) ) { + // remove the method from another interface hierarchy that is overridden by the executable to add + it.remove(); + return true; + } + } + + return true; + } + + private void addEnclosedFieldsInHierarchy( List alreadyAdded, + TypeElement element, TypeElement parentType) { + if ( element != parentType ) { // otherwise the element was already checked for replacement + element = replaceTypeElementIfNecessary( element ); + } + + if ( element.asType().getKind() == TypeKind.ERROR ) { + throw new TypeHierarchyErroneousException( element ); + } + + addFields( alreadyAdded, fieldsIn( element.getEnclosedElements() ) ); + + if ( hasNonObjectSuperclass( element ) ) { + addEnclosedFieldsInHierarchy( + alreadyAdded, + asTypeElement( element.getSuperclass() ), + parentType + ); + } + } + + private static void addFields(List alreadyCollected, List variablesToAdd) { + List safeToAdd = new ArrayList<>( variablesToAdd.size() ); + safeToAdd.addAll( variablesToAdd ); + + alreadyCollected.addAll( 0, safeToAdd ); + } + + /** + * @param element the type element to check + * @return {@code true}, iff the type has a super-class that is not java.lang.Object + */ + private boolean hasNonObjectSuperclass(TypeElement element) { + if ( element.getSuperclass().getKind() == TypeKind.ERROR ) { + throw new TypeHierarchyErroneousException( element ); + } + + return element.getSuperclass().getKind() == TypeKind.DECLARED + && !asTypeElement( element.getSuperclass() ).getQualifiedName().toString().equals( "java.lang.Object" ); + } + + /** + * @param mirror the type positionHint + * @return the corresponding type element + */ + private TypeElement asTypeElement(TypeMirror mirror) { + return (TypeElement) ( (DeclaredType) mirror ).asElement(); + } + + /** + * Checks whether the {@code executable} does not have a private modifier. + * + * @param executable the executable to check + * @return {@code true}, iff the executable does not have a private modifier + */ + private boolean isNotPrivate(ExecutableElement executable) { + return !executable.getModifiers().contains( Modifier.PRIVATE ); + } + + protected abstract TypeElement replaceTypeElementIfNecessary(TypeElement element); + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/AbstractTypeUtilsDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/AbstractTypeUtilsDecorator.java new file mode 100644 index 0000000000..2f7c4d604d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/AbstractTypeUtilsDecorator.java @@ -0,0 +1,136 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.util.List; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.lang.model.type.ArrayType; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.ExecutableType; +import javax.lang.model.type.NoType; +import javax.lang.model.type.NullType; +import javax.lang.model.type.PrimitiveType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.WildcardType; +import javax.lang.model.util.Types; + +/** + * Replaces the usage of {@link TypeUtils} within MapStruct by delegating to the original implementation or to our + * specific workarounds if necessary. + * + * @author Andreas Gudian + */ +public abstract class AbstractTypeUtilsDecorator implements TypeUtils { + + private final Types delegate; + + AbstractTypeUtilsDecorator(ProcessingEnvironment processingEnv) { + this.delegate = processingEnv.getTypeUtils(); + } + + @Override + public Element asElement(TypeMirror t) { + return delegate.asElement( t ); + } + + @Override + public boolean isSameType(TypeMirror t1, TypeMirror t2) { + return delegate.isSameType( t1, t2 ); + } + + @Override + public boolean isSubtype(TypeMirror t1, TypeMirror t2) { + return delegate.isSubtype( t1, t2 ); + } + + @Override + public boolean isAssignable(TypeMirror t1, TypeMirror t2) { + return delegate.isAssignable( t1, t2 ); + } + + @Override + public boolean contains(TypeMirror t1, TypeMirror t2) { + return delegate.contains( t1, t2 ); + } + + @Override + public boolean isSubsignature(ExecutableType m1, ExecutableType m2) { + return delegate.isSubsignature( m1, m2 ); + } + + @Override + public List directSupertypes(TypeMirror t) { + return delegate.directSupertypes( t ); + } + + @Override + public TypeMirror erasure(TypeMirror t) { + return delegate.erasure( t ); + } + + @Override + public TypeElement boxedClass(PrimitiveType p) { + return delegate.boxedClass( p ); + } + + @Override + public PrimitiveType unboxedType(TypeMirror t) { + return delegate.unboxedType( t ); + } + + @Override + public TypeMirror capture(TypeMirror t) { + return delegate.capture( t ); + } + + @Override + public PrimitiveType getPrimitiveType(TypeKind kind) { + return delegate.getPrimitiveType( kind ); + } + + @Override + public NullType getNullType() { + return delegate.getNullType(); + } + + @Override + public NoType getNoType(TypeKind kind) { + return delegate.getNoType( kind ); + } + + @Override + public ArrayType getArrayType(TypeMirror componentType) { + return delegate.getArrayType( componentType ); + } + + @Override + public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) { + return delegate.getWildcardType( extendsBound, superBound ); + } + + @Override + public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { + return delegate.getDeclaredType( typeElem, typeArgs ); + } + + @Override + public DeclaredType getDeclaredType(DeclaredType containing, TypeElement typeElem, TypeMirror... typeArgs) { + return delegate.getDeclaredType( containing, typeElem, typeArgs ); + } + + @Override + public TypeMirror asMemberOf(DeclaredType containing, Element element) { + return delegate.asMemberOf( containing, element ); + } + + @Override + public boolean isSubtypeErased(TypeMirror t1, TypeMirror t2) { + return delegate.isSubtype( erasure( t1 ), erasure( t2 ) ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/AccessorNamingUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/util/AccessorNamingUtils.java index 247776c547..8025acfeb1 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/AccessorNamingUtils.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/AccessorNamingUtils.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; @@ -23,15 +10,15 @@ import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.SimpleElementVisitor6; -import javax.lang.model.util.SimpleTypeVisitor6; +import javax.lang.model.util.SimpleElementVisitor8; +import javax.lang.model.util.SimpleTypeVisitor8; import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; +import org.mapstruct.ap.internal.util.accessor.AccessorType; import org.mapstruct.ap.spi.AccessorNamingStrategy; import org.mapstruct.ap.spi.MethodType; -import static org.mapstruct.ap.internal.util.Executables.isPublic; +import static org.mapstruct.ap.internal.util.Executables.isPublicNotStatic; /** * Utils for working with the {@link AccessorNamingStrategy}. @@ -46,46 +33,38 @@ public AccessorNamingUtils(AccessorNamingStrategy accessorNamingStrategy) { this.accessorNamingStrategy = accessorNamingStrategy; } - public boolean isGetterMethod(Accessor method) { - ExecutableElement executable = method.getExecutable(); - return executable != null && isPublic( method ) && + public boolean isGetterMethod(ExecutableElement executable) { + return executable != null && isPublicNotStatic( executable ) && executable.getParameters().isEmpty() && accessorNamingStrategy.getMethodType( executable ) == MethodType.GETTER; } - public boolean isPresenceCheckMethod(Accessor method) { - if ( !( method instanceof ExecutableElementAccessor ) ) { - return false; - } - ExecutableElement executable = method.getExecutable(); + public boolean isPresenceCheckMethod(ExecutableElement executable) { + return executable != null - && isPublic( method ) + && isPublicNotStatic( executable ) && executable.getParameters().isEmpty() && ( executable.getReturnType().getKind() == TypeKind.BOOLEAN || "java.lang.Boolean".equals( getQualifiedName( executable.getReturnType() ) ) ) && accessorNamingStrategy.getMethodType( executable ) == MethodType.PRESENCE_CHECKER; } - public boolean isSetterMethod(Accessor method) { - ExecutableElement executable = method.getExecutable(); + public boolean isSetterMethod(ExecutableElement executable) { return executable != null - && isPublic( method ) + && isPublicNotStatic( executable ) && executable.getParameters().size() == 1 && accessorNamingStrategy.getMethodType( executable ) == MethodType.SETTER; } - public boolean isAdderMethod(Accessor method) { - ExecutableElement executable = method.getExecutable(); + public boolean isAdderMethod(ExecutableElement executable) { return executable != null - && isPublic( method ) + && isPublicNotStatic( executable ) && executable.getParameters().size() == 1 && accessorNamingStrategy.getMethodType( executable ) == MethodType.ADDER; } - public String getPropertyName(Accessor accessor) { - ExecutableElement executable = accessor.getExecutable(); - return executable != null ? accessorNamingStrategy.getPropertyName( executable ) : - accessor.getSimpleName().toString(); + public String getPropertyName(ExecutableElement executable) { + return accessorNamingStrategy.getPropertyName( executable ); } /** @@ -95,13 +74,17 @@ public String getPropertyName(Accessor accessor) { * {@code addChild(Child v)}, the element name would be 'Child'. */ public String getElementNameForAdder(Accessor adderMethod) { - ExecutableElement executable = adderMethod.getExecutable(); - return executable != null ? accessorNamingStrategy.getElementName( executable ) : null; + if ( adderMethod.getAccessorType() == AccessorType.ADDER ) { + return accessorNamingStrategy.getElementName( (ExecutableElement) adderMethod.getElement() ); + } + else { + return null; + } } private static String getQualifiedName(TypeMirror type) { DeclaredType declaredType = type.accept( - new SimpleTypeVisitor6() { + new SimpleTypeVisitor8() { @Override public DeclaredType visitDeclared(DeclaredType t, Void p) { return t; @@ -115,7 +98,7 @@ public DeclaredType visitDeclared(DeclaredType t, Void p) { } TypeElement typeElement = declaredType.asElement().accept( - new SimpleElementVisitor6() { + new SimpleElementVisitor8() { @Override public TypeElement visitType(TypeElement e, Void p) { return e; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessingException.java b/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessingException.java index 481c840a03..29c73d2691 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessingException.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessingException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java b/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java index 418b83f679..9f8523efa0 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/AnnotationProcessorContext.java @@ -1,59 +1,74 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.ServiceLoader; - -import javax.lang.model.element.TypeElement; +import javax.annotation.processing.Messager; import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic; import org.mapstruct.ap.spi.AccessorNamingStrategy; import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; import org.mapstruct.ap.spi.BuilderProvider; import org.mapstruct.ap.spi.DefaultAccessorNamingStrategy; import org.mapstruct.ap.spi.DefaultBuilderProvider; +import org.mapstruct.ap.spi.DefaultEnumMappingStrategy; +import org.mapstruct.ap.spi.EnumMappingStrategy; +import org.mapstruct.ap.spi.EnumTransformationStrategy; +import org.mapstruct.ap.spi.FreeBuilderAccessorNamingStrategy; import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy; import org.mapstruct.ap.spi.ImmutablesBuilderProvider; +import org.mapstruct.ap.spi.MapStructProcessingEnvironment; +import org.mapstruct.ap.spi.NoOpBuilderProvider; /** * Keeps contextual data in the scope of the entire annotation processor ("application scope"). * * @author Gunnar Morling */ -public class AnnotationProcessorContext { +public class AnnotationProcessorContext implements MapStructProcessingEnvironment { private List astModifyingAnnotationProcessors; private BuilderProvider builderProvider; private AccessorNamingStrategy accessorNamingStrategy; + private EnumMappingStrategy enumMappingStrategy; private boolean initialized; + private Map enumTransformationStrategies; private AccessorNamingUtils accessorNaming; + private NullabilityResolver nullabilityResolver; private Elements elementUtils; + private Types typeUtils; + private Messager messager; + private boolean disableBuilder; + private boolean disableJSpecify; + private boolean verbose; - public AnnotationProcessorContext(Elements elementUtils) { + private Map options; + + public AnnotationProcessorContext(Elements elementUtils, Types typeUtils, Messager messager, boolean disableBuilder, + boolean disableJSpecify, boolean verbose, Map options) { astModifyingAnnotationProcessors = java.util.Collections.unmodifiableList( - findAstModifyingAnnotationProcessors() ); + findAstModifyingAnnotationProcessors( messager ) ); this.elementUtils = elementUtils; + this.typeUtils = typeUtils; + this.messager = messager; + this.disableBuilder = disableBuilder; + this.disableJSpecify = disableJSpecify; + this.verbose = verbose; + this.options = java.util.Collections.unmodifiableMap( options ); } /** @@ -70,35 +85,169 @@ private void initialize() { AccessorNamingStrategy defaultAccessorNamingStrategy; BuilderProvider defaultBuilderProvider; - TypeElement immutableElement = elementUtils.getTypeElement( ImmutablesConstants.IMMUTABLE_FQN ); - if ( immutableElement == null ) { - defaultAccessorNamingStrategy = new DefaultAccessorNamingStrategy(); + if ( elementUtils.getTypeElement( ImmutablesConstants.IMMUTABLE_FQN ) != null ) { + defaultAccessorNamingStrategy = new ImmutablesAccessorNamingStrategy(); + defaultBuilderProvider = new ImmutablesBuilderProvider(); + if ( verbose ) { + messager.printMessage( Diagnostic.Kind.NOTE, "MapStruct: Immutables found on classpath" ); + } + } + else if ( elementUtils.getTypeElement( FreeBuilderConstants.FREE_BUILDER_FQN ) != null ) { + defaultAccessorNamingStrategy = new FreeBuilderAccessorNamingStrategy(); defaultBuilderProvider = new DefaultBuilderProvider(); + if ( verbose ) { + messager.printMessage( Diagnostic.Kind.NOTE, "MapStruct: Freebuilder found on classpath" ); + } } else { - defaultAccessorNamingStrategy = new ImmutablesAccessorNamingStrategy(); - defaultBuilderProvider = new ImmutablesBuilderProvider(); + defaultAccessorNamingStrategy = new DefaultAccessorNamingStrategy(); + defaultBuilderProvider = new DefaultBuilderProvider(); } this.accessorNamingStrategy = Services.get( AccessorNamingStrategy.class, defaultAccessorNamingStrategy ); - this.builderProvider = Services.get( BuilderProvider.class, defaultBuilderProvider ); + this.accessorNamingStrategy.init( this ); + if ( verbose ) { + messager.printMessage( + Diagnostic.Kind.NOTE, + "MapStruct: Using accessor naming strategy: " + + this.accessorNamingStrategy.getClass().getCanonicalName() + ); + } + this.builderProvider = this.disableBuilder ? + new NoOpBuilderProvider() : + Services.get( BuilderProvider.class, defaultBuilderProvider ); + this.builderProvider.init( this ); + if ( verbose ) { + messager.printMessage( + Diagnostic.Kind.NOTE, + "MapStruct: Using builder provider: " + this.builderProvider.getClass().getCanonicalName() + ); + } this.accessorNaming = new AccessorNamingUtils( this.accessorNamingStrategy ); + this.nullabilityResolver = new NullabilityResolver( !this.disableJSpecify ); + + this.enumMappingStrategy = Services.get( EnumMappingStrategy.class, new DefaultEnumMappingStrategy() ); + this.enumMappingStrategy.init( this ); + if ( verbose ) { + messager.printMessage( + Diagnostic.Kind.NOTE, + "MapStruct: Using enum naming strategy: " + + this.enumMappingStrategy.getClass().getCanonicalName() + ); + } + + this.enumTransformationStrategies = new LinkedHashMap<>(); + ServiceLoader transformationStrategiesLoader = ServiceLoader.load( + EnumTransformationStrategy.class, + AnnotationProcessorContext.class.getClassLoader() + ); + + for ( EnumTransformationStrategy transformationStrategy : transformationStrategiesLoader ) { + String transformationStrategyName = transformationStrategy.getStrategyName(); + if ( enumTransformationStrategies.containsKey( transformationStrategyName ) ) { + throw new IllegalStateException( + "Multiple EnumTransformationStrategies are using the same ma,e. Found: " + + enumTransformationStrategies.get( transformationStrategyName ) + " and " + + transformationStrategy + " for name " + transformationStrategyName ); + } + + transformationStrategy.init( this ); + enumTransformationStrategies.put( transformationStrategyName, transformationStrategy ); + } + + this.initialized = true; } - private static List findAstModifyingAnnotationProcessors() { - List processors = new ArrayList(); + private static List findAstModifyingAnnotationProcessors(Messager messager) { + List processors = new ArrayList<>(); ServiceLoader loader = ServiceLoader.load( AstModifyingAnnotationProcessor.class, AnnotationProcessorContext.class.getClassLoader() ); - for ( Iterator it = loader.iterator(); it.hasNext(); ) { - processors.add( it.next() ); + // Lombok packages an AstModifyingAnnotationProcessor as part of their jar + // this leads to problems within Eclipse when lombok is used as an agent + // Therefore we are wrapping this into an iterator that can handle exceptions by ignoring + // the faulty processor + Iterator loaderIterator = new FaultyDelegatingIterator( + messager, + loader.iterator() + ); + + while ( loaderIterator.hasNext() ) { + AstModifyingAnnotationProcessor processor = loaderIterator.next(); + if ( processor != null ) { + processors.add( processor ); + } } return processors; } + private static class FaultyDelegatingIterator implements Iterator { + + private final Messager messager; + private final Iterator delegate; + + private FaultyDelegatingIterator(Messager messager, + Iterator delegate) { + this.messager = messager; + this.delegate = delegate; + } + + @Override + public boolean hasNext() { + // Check the delegate maximum of 5 times + // before returning false + int failures = 5; + while ( failures > 0 ) { + try { + return delegate.hasNext(); + } + catch ( Throwable t ) { + failures--; + logFailure( t ); + } + } + + return false; + } + + @Override + public AstModifyingAnnotationProcessor next() { + try { + return delegate.next(); + } + catch ( Throwable t ) { + logFailure( t ); + return null; + } + } + + private void logFailure(Throwable t) { + StringWriter sw = new StringWriter(); + t.printStackTrace( new PrintWriter( sw ) ); + + String reportableStacktrace = sw.toString().replace( System.lineSeparator(), " " ); + + messager.printMessage( + Diagnostic.Kind.WARNING, + "Failed to read AstModifyingAnnotationProcessor. Reading next processor. Reason: " + + reportableStacktrace + ); + } + } + + @Override + public Elements getElementUtils() { + return elementUtils; + } + + @Override + public Types getTypeUtils() { + return typeUtils; + } + public List getAstModifyingAnnotationProcessors() { return astModifyingAnnotationProcessors; } @@ -108,13 +257,32 @@ public AccessorNamingUtils getAccessorNaming() { return accessorNaming; } + public NullabilityResolver getNullabilityResolver() { + initialize(); + return nullabilityResolver; + } + public AccessorNamingStrategy getAccessorNamingStrategy() { initialize(); return accessorNamingStrategy; } + public EnumMappingStrategy getEnumMappingStrategy() { + initialize(); + return enumMappingStrategy; + } + public BuilderProvider getBuilderProvider() { initialize(); return builderProvider; } + + public Map getEnumTransformationStrategies() { + initialize(); + return enumTransformationStrategies; + } + + public Map getOptions() { + return this.options; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/ClassUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/util/ClassUtils.java deleted file mode 100644 index 95d5bfbe99..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/ClassUtils.java +++ /dev/null @@ -1,89 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util; - -/** - * Utilities for working with classes. It is mainly needed because using the {@link javax.lang.model.util.Elements} - * is not always correct. For example when compiling with JDK 9 and source version 8 classes from different modules - * are available by {@link javax.lang.model.util.Elements#getTypeElement(CharSequence)} but they are actually not - * if those modules are not added during compilation. - * - * @author Filip Hrisafov - */ -class ClassUtils { - - private ClassUtils() { - } - - /** - * Determine whether the {@link Class} identified by the supplied name is present - * and can be loaded. Will return {@code false} if either the class or - * one of its dependencies is not present or cannot be loaded. - * - * @param className the name of the class to check - * @param classLoader the class loader to use - * (may be {@code null}, which indicates the default class loader) - * - * @return whether the specified class is present - */ - static boolean isPresent(String className, ClassLoader classLoader) { - try { - ClassLoader classLoaderToUse = classLoader; - if ( classLoaderToUse == null ) { - classLoaderToUse = getDefaultClassLoader(); - } - classLoaderToUse.loadClass( className ); - return true; - } - catch ( ClassNotFoundException ex ) { - // Class or one of its dependencies is not present... - return false; - } - } - - /** - * Return the default ClassLoader to use: typically the thread context - * ClassLoader, if available; the ClassLoader that loaded the ClassUtils - * class will be used as fallback. - *

      Call this method if you intend to use the thread context ClassLoader - * in a scenario where you absolutely need a non-null ClassLoader reference: - * for example, for class path resource loading (but not necessarily for - * {@code Class.forName}, which accepts a {@code null} ClassLoader - * reference as well). - * - * @return the default ClassLoader (never {@code null}) - * - * @see Thread#getContextClassLoader() - */ - private static ClassLoader getDefaultClassLoader() { - ClassLoader cl = null; - try { - cl = Thread.currentThread().getContextClassLoader(); - } - catch ( Throwable ex ) { - // Cannot access thread context ClassLoader - falling back to system class loader... - } - if ( cl == null ) { - // No thread context class loader -> use class loader of this class. - cl = ClassUtils.class.getClassLoader(); - } - return cl; - } - -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Collections.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Collections.java index 05715d9fab..365efc56ce 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Collections.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Collections.java @@ -1,28 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; /** @@ -35,36 +22,23 @@ public class Collections { private Collections() { } + @SafeVarargs public static Set asSet(T... elements) { - Set set = new HashSet(); - - for ( T element : elements ) { - set.add( element ); - } - + Set set = new HashSet<>( elements.length ); + java.util.Collections.addAll( set, elements ); return set; } - public static List newArrayList(T... elements) { - List list = new ArrayList(); - - list.addAll( Arrays.asList( elements ) ); - - return list; - } - + @SafeVarargs public static Set asSet(Collection collection, T... elements) { - Set set = new HashSet( collection ); - - for ( T element : elements ) { - set.add( element ); - } - + Set set = new HashSet<>( collection.size() + elements.length ); + java.util.Collections.addAll( set, elements ); return set; } + @SafeVarargs public static Set asSet(Collection collection, Collection... elements) { - Set set = new HashSet( collection ); + Set set = new HashSet<>( collection ); for ( Collection element : elements ) { set.addAll( element ); @@ -82,7 +56,7 @@ public static T last(List list) { } public static List join(List a, List b) { - List result = new ArrayList( a.size() + b.size() ); + List result = new ArrayList<>( a.size() + b.size() ); result.addAll( a ); result.addAll( b ); @@ -90,14 +64,16 @@ public static List join(List a, List b) { return result; } - public static boolean hasNonNullElements(Iterable elements) { - if ( elements != null ) { - for ( E e : elements ) { - if ( e != null ) { - return true; - } - } - } - return false; + public static Map.Entry first(Map map) { + return map.entrySet().iterator().next(); } + + public static V firstValue(Map map) { + return first( map ).getValue(); + } + + public static K firstKey(Map map) { + return first( map ).getKey(); + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/EclipseElementUtilsDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/EclipseElementUtilsDecorator.java new file mode 100644 index 0000000000..3c1dc84d36 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/EclipseElementUtilsDecorator.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.Elements; + +public class EclipseElementUtilsDecorator extends AbstractElementUtilsDecorator { + + private final Elements delegate; + + EclipseElementUtilsDecorator(ProcessingEnvironment processingEnv, TypeElement mapperElement) { + super( processingEnv, mapperElement ); + this.delegate = processingEnv.getElementUtils(); + } + + /** + * When running during Eclipse Incremental Compilation, we might get a TypeElement that has an UnresolvedTypeBinding + * and which is not automatically resolved. In that case, getEnclosedElements returns an empty list. We take that as + * a hint to check if the TypeElement resolved by FQN might have any enclosed elements and, if so, return the + * resolved element. + * + * @param element the original element + * @return the element freshly resolved using the qualified name, if the original element did not return any + * enclosed elements, whereas the resolved element does return enclosed elements. + */ + protected TypeElement replaceTypeElementIfNecessary(TypeElement element) { + if ( element.getEnclosedElements().isEmpty() ) { + TypeElement resolvedByName = delegate.getTypeElement( element.getQualifiedName() ); + if ( resolvedByName != null && !resolvedByName.getEnclosedElements().isEmpty() ) { + return resolvedByName; + } + } + return element; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/EclipseTypeUtilsDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/EclipseTypeUtilsDecorator.java new file mode 100644 index 0000000000..380df67bd5 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/EclipseTypeUtilsDecorator.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.type.TypeVariable; +import javax.lang.model.type.WildcardType; +import javax.lang.model.util.Types; + +public class EclipseTypeUtilsDecorator extends AbstractTypeUtilsDecorator { + + private final Types delegate; + + EclipseTypeUtilsDecorator(ProcessingEnvironment processingEnv) { + super( processingEnv ); + this.delegate = processingEnv.getTypeUtils(); + } + + @Override + public boolean contains(TypeMirror t1, TypeMirror t2) { + if ( TypeKind.TYPEVAR == t2.getKind() ) { + return containsType( t1, ( (TypeVariable) t2 ).getLowerBound() ); + } + else { + return containsType( t1, t2 ); + } + } + + private boolean containsType(TypeMirror t1, TypeMirror t2) { + + boolean result = false; + if ( TypeKind.DECLARED == t2.getKind() ) { + if ( TypeKind.WILDCARD == t1.getKind() ) { + WildcardType wct = (WildcardType) t1; + if ( wct.getExtendsBound() != null ) { + result = isAssignable( t2, wct.getExtendsBound() ); + } + else if ( wct.getSuperBound() != null ) { + result = isAssignable( wct.getSuperBound(), t2 ); + } + else { + result = isAssignable( t2, wct ); + } + } + } + return result; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/ElementUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/util/ElementUtils.java new file mode 100644 index 0000000000..3e026cde80 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/ElementUtils.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.util.List; +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.util.Elements; + +import org.mapstruct.ap.internal.version.VersionInformation; + +public interface ElementUtils extends Elements { + + static ElementUtils create(ProcessingEnvironment processingEnvironment, VersionInformation info, + TypeElement mapperElement) { + if ( info.isEclipseJDTCompiler() ) { + return new EclipseElementUtilsDecorator( processingEnvironment, mapperElement ); + } + else { + return new JavacElementUtilsDecorator( processingEnvironment, mapperElement ); + } + } + + /** + * Finds all executable elements within the given type element, including executable elements defined in super + * classes and implemented interfaces. Methods defined in {@link java.lang.Object}, + * implementations of {@link java.lang.Object#equals(Object)} and private methods are ignored + * + * @param element the element to inspect + * @return the executable elements usable in the type + */ + List getAllEnclosedExecutableElements(TypeElement element); + + /** + * Finds all variable elements within the given type element, including variable + * elements defined in super classes and implemented interfaces and including the fields in the . + * + * @param element the element to inspect + * @return the executable elements usable in the type + */ + List getAllEnclosedFields(TypeElement element); +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java index e4e14c39b8..c845450e13 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Executables.java @@ -1,48 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; -import static javax.lang.model.util.ElementFilter.fieldsIn; -import static javax.lang.model.util.ElementFilter.methodsIn; -import static org.mapstruct.ap.internal.util.workarounds.SpecificCompilerWorkarounds.replaceTypeElementIfNecessary; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; -import java.util.ListIterator; - import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import javax.lang.model.element.TypeElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import org.mapstruct.ap.internal.prism.AfterMappingPrism; -import org.mapstruct.ap.internal.prism.BeforeMappingPrism; +import org.mapstruct.ap.internal.gem.AfterMappingGem; +import org.mapstruct.ap.internal.gem.BeforeMappingGem; import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; -import org.mapstruct.ap.internal.util.accessor.VariableElementAccessor; -import org.mapstruct.ap.spi.TypeHierarchyErroneousException; /** * Provides functionality around {@link ExecutableElement}s. @@ -51,41 +19,19 @@ */ public class Executables { - private static final Method DEFAULT_METHOD; - - static { - Method method; - try { - method = ExecutableElement.class.getMethod( "isDefault" ); - } - catch ( NoSuchMethodException e ) { - method = null; - } - DEFAULT_METHOD = method; - } - private Executables() { } - /** - * An {@link Accessor} is a field accessor, if it doesn't have an executable element, is public and it is not - * static. - * - * @param accessor the accessor to ber checked - * - * @return {@code true} if the {@code accessor} is for a {@code public} non {@code static} field. - */ - public static boolean isFieldAccessor(Accessor accessor) { - ExecutableElement executable = accessor.getExecutable(); - return executable == null && isPublic( accessor ) && isNotStatic( accessor ); + static boolean isPublicNotStatic(ExecutableElement method) { + return isPublic( method ) && isNotStatic( method ); } - static boolean isPublic(Accessor method) { + static boolean isPublic(ExecutableElement method) { return method.getModifiers().contains( Modifier.PUBLIC ); } - private static boolean isNotStatic(Accessor accessor) { - return !accessor.getModifiers().contains( Modifier.STATIC ); + private static boolean isNotStatic(ExecutableElement method) { + return !method.getModifiers().contains( Modifier.STATIC ); } public static boolean isFinal(Accessor accessor) { @@ -93,182 +39,7 @@ public static boolean isFinal(Accessor accessor) { } public static boolean isDefaultMethod(ExecutableElement method) { - try { - return DEFAULT_METHOD != null && Boolean.TRUE.equals( DEFAULT_METHOD.invoke( method ) ); - } - catch ( IllegalAccessException e ) { - return false; - } - catch ( InvocationTargetException e ) { - return false; - } - } - - /** - * @param mirror the type mirror - * - * @return the corresponding type element - */ - private static TypeElement asTypeElement(TypeMirror mirror) { - return (TypeElement) ( (DeclaredType) mirror ).asElement(); - } - - /** - * Finds all executable elements within the given type element, including executable elements defined in super - * classes and implemented interfaces. Methods defined in {@link java.lang.Object} are ignored, as well as - * implementations of {@link java.lang.Object#equals(Object)}. - * - * @param elementUtils element helper - * @param element the element to inspect - * - * @return the executable elements usable in the type - */ - public static List getAllEnclosedExecutableElements(Elements elementUtils, TypeElement element) { - List executables = new ArrayList(); - for ( Accessor accessor : getAllEnclosedAccessors( elementUtils, element ) ) { - if ( accessor.getExecutable() != null ) { - executables.add( accessor.getExecutable() ); - } - } - return executables; - } - - /** - * Finds all executable elements/variable elements within the given type element, including executable/variable - * elements defined in super classes and implemented interfaces and including the fields in the . Methods defined - * in {@link java.lang.Object} are ignored, as well as implementations of {@link java.lang.Object#equals(Object)}. - * - * @param elementUtils element helper - * @param element the element to inspect - * - * @return the executable elements usable in the type - */ - public static List getAllEnclosedAccessors(Elements elementUtils, TypeElement element) { - List enclosedElements = new ArrayList(); - element = replaceTypeElementIfNecessary( elementUtils, element ); - addEnclosedElementsInHierarchy( elementUtils, enclosedElements, element, element ); - - return enclosedElements; - } - - private static void addEnclosedElementsInHierarchy(Elements elementUtils, List alreadyAdded, - TypeElement element, TypeElement parentType) { - if ( element != parentType ) { // otherwise the element was already checked for replacement - element = replaceTypeElementIfNecessary( elementUtils, element ); - } - - if ( element.asType().getKind() == TypeKind.ERROR ) { - throw new TypeHierarchyErroneousException( element ); - } - - addNotYetOverridden( elementUtils, alreadyAdded, methodsIn( element.getEnclosedElements() ), parentType ); - addFields( alreadyAdded, fieldsIn( element.getEnclosedElements() ) ); - - if ( hasNonObjectSuperclass( element ) ) { - addEnclosedElementsInHierarchy( - elementUtils, - alreadyAdded, - asTypeElement( element.getSuperclass() ), - parentType - ); - } - - for ( TypeMirror interfaceType : element.getInterfaces() ) { - addEnclosedElementsInHierarchy( - elementUtils, - alreadyAdded, - asTypeElement( interfaceType ), - parentType - ); - } - - } - - /** - * @param alreadyCollected methods that have already been collected and to which the not-yet-overridden methods will - * be added - * @param methodsToAdd methods to add to alreadyAdded, if they are not yet overridden by an element in the list - * @param parentType the type for with elements are collected - */ - private static void addNotYetOverridden(Elements elementUtils, List alreadyCollected, - List methodsToAdd, TypeElement parentType) { - List safeToAdd = new ArrayList( methodsToAdd.size() ); - for ( ExecutableElement toAdd : methodsToAdd ) { - if ( isNotObjectEquals( toAdd ) - && wasNotYetOverridden( elementUtils, alreadyCollected, toAdd, parentType ) ) { - safeToAdd.add( new ExecutableElementAccessor( toAdd ) ); - } - } - - alreadyCollected.addAll( 0, safeToAdd ); - } - - private static void addFields(List alreadyCollected, List variablesToAdd) { - List safeToAdd = new ArrayList( variablesToAdd.size() ); - for ( VariableElement toAdd : variablesToAdd ) { - safeToAdd.add( new VariableElementAccessor( toAdd ) ); - } - - alreadyCollected.addAll( 0, safeToAdd ); - } - - - /** - * @param executable the executable to check - * - * @return {@code true}, iff the executable does not represent {@link java.lang.Object#equals(Object)} or an - * overridden version of it - */ - private static boolean isNotObjectEquals(ExecutableElement executable) { - if ( executable.getSimpleName().contentEquals( "equals" ) && executable.getParameters().size() == 1 - && asTypeElement( executable.getParameters().get( 0 ).asType() ).getQualifiedName().contentEquals( - "java.lang.Object" - ) ) { - return false; - } - return true; - } - - /** - * @param elementUtils the elementUtils - * @param alreadyCollected the list of already collected methods of one type hierarchy (order is from sub-types to - * super-types) - * @param executable the method to check - * @param parentType the type for which elements are collected - * @return {@code true}, iff the given executable was not yet overridden by a method in the given list. - */ - private static boolean wasNotYetOverridden(Elements elementUtils, List alreadyCollected, - ExecutableElement executable, TypeElement parentType) { - for ( ListIterator it = alreadyCollected.listIterator(); it.hasNext(); ) { - ExecutableElement executableInSubtype = it.next().getExecutable(); - if ( executableInSubtype == null ) { - continue; - } - if ( elementUtils.overrides( executableInSubtype, executable, parentType ) ) { - return false; - } - else if ( elementUtils.overrides( executable, executableInSubtype, parentType ) ) { - // remove the method from another interface hierarchy that is overridden by the executable to add - it.remove(); - return true; - } - } - - return true; - } - - /** - * @param element the type element to check - * - * @return {@code true}, iff the type has a super-class that is not java.lang.Object - */ - private static boolean hasNonObjectSuperclass(TypeElement element) { - if ( element.getSuperclass().getKind() == TypeKind.ERROR ) { - throw new TypeHierarchyErroneousException( element ); - } - - return element.getSuperclass().getKind() == TypeKind.DECLARED - && !asTypeElement( element.getSuperclass() ).getQualifiedName().toString().equals( "java.lang.Object" ); + return method.isDefault(); } /** @@ -285,7 +56,7 @@ public static boolean isLifecycleCallbackMethod(ExecutableElement executableElem * @return {@code true}, if the executable element is a method annotated with {@code @AfterMapping} */ public static boolean isAfterMappingMethod(ExecutableElement executableElement) { - return AfterMappingPrism.getInstanceOn( executableElement ) != null; + return AfterMappingGem.instanceOn( executableElement ) != null; } /** @@ -293,6 +64,6 @@ public static boolean isAfterMappingMethod(ExecutableElement executableElement) * @return {@code true}, if the executable element is a method annotated with {@code @BeforeMapping} */ public static boolean isBeforeMappingMethod(ExecutableElement executableElement) { - return BeforeMappingPrism.getInstanceOn( executableElement ) != null; + return BeforeMappingGem.instanceOn( executableElement ) != null; } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Extractor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Extractor.java index ec70657afd..7d6a87e8a4 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Extractor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Extractor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Fields.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Fields.java new file mode 100644 index 0000000000..b2f8ac1442 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Fields.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; + +/** + * Provides functionality around {@link VariableElement}s. + * + * @author Sjaak Derksen + */ +public class Fields { + + private Fields() { + } + + public static boolean isFieldAccessor(VariableElement method) { + return isPublic( method ) && isNotStatic( method ); + } + + static boolean isPublic(VariableElement method) { + return method.getModifiers().contains( Modifier.PUBLIC ); + } + + private static boolean isNotStatic(VariableElement method) { + return !method.getModifiers().contains( Modifier.STATIC ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Filters.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Filters.java index b50711edf0..6492270705 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Filters.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Filters.java @@ -1,98 +1,145 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; - +import java.util.Map; +import java.util.function.BiFunction; +import java.util.stream.Collectors; import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.ExecutableType; +import javax.lang.model.type.TypeMirror; import org.mapstruct.ap.internal.util.accessor.Accessor; -import org.mapstruct.ap.internal.util.accessor.ExecutableElementAccessor; +import org.mapstruct.ap.internal.util.accessor.ElementAccessor; +import org.mapstruct.ap.internal.util.accessor.ReadAccessor; + +import static org.mapstruct.ap.internal.util.Collections.first; +import static org.mapstruct.ap.internal.util.accessor.AccessorType.ADDER; +import static org.mapstruct.ap.internal.util.accessor.AccessorType.SETTER; /** * Filter methods for working with {@link Element} collections. * * @author Gunnar Morling + * @author Filip Hrisafov */ public class Filters { - private Filters() { + private static final Method RECORD_COMPONENTS_METHOD; + + static { + Method recordComponentsMethod; + try { + recordComponentsMethod = TypeElement.class.getMethod( "getRecordComponents" ); + } + catch ( NoSuchMethodException e ) { + recordComponentsMethod = null; + } + RECORD_COMPONENTS_METHOD = recordComponentsMethod; } - public static List getterMethodsIn(AccessorNamingUtils accessorNaming, List elements) { - List getterMethods = new LinkedList(); + private final AccessorNamingUtils accessorNaming; + private final TypeUtils typeUtils; + private final TypeMirror typeMirror; - for ( Accessor method : elements ) { - if ( accessorNaming.isGetterMethod( method ) ) { - getterMethods.add( method ); - } - } + public Filters(AccessorNamingUtils accessorNaming, TypeUtils typeUtils, TypeMirror typeMirror) { + this.accessorNaming = accessorNaming; + this.typeUtils = typeUtils; + this.typeMirror = typeMirror; + } - return getterMethods; + public List getterMethodsIn(List elements) { + return elements.stream() + .filter( accessorNaming::isGetterMethod ) + .map( method -> ReadAccessor.fromGetter( method, getReturnType( method ) ) ) + .collect( Collectors.toCollection( LinkedList::new ) ); } - public static List fieldsIn(List accessors) { - List fieldAccessors = new LinkedList(); + @SuppressWarnings("unchecked") + public List recordComponentsIn(TypeElement typeElement) { + if ( RECORD_COMPONENTS_METHOD == null ) { + return java.util.Collections.emptyList(); + } + + try { + return (List) RECORD_COMPONENTS_METHOD.invoke( typeElement ); + } + catch ( IllegalAccessException | InvocationTargetException e ) { + return java.util.Collections.emptyList(); + } + } - for ( Accessor accessor : accessors ) { - if ( Executables.isFieldAccessor( accessor ) ) { - fieldAccessors.add( accessor ); - } + public Map recordAccessorsIn(Collection recordComponents) { + if ( recordComponents.isEmpty() ) { + return java.util.Collections.emptyMap(); + } + Map recordAccessors = new LinkedHashMap<>(); + for ( Element recordComponent : recordComponents ) { + recordAccessors.put( + recordComponent.getSimpleName().toString(), + ReadAccessor.fromRecordComponent( + recordComponent, + typeUtils.asMemberOf( (DeclaredType) typeMirror, recordComponent ) + ) + ); } - return fieldAccessors; + return recordAccessors; } - public static List presenceCheckMethodsIn(AccessorNamingUtils accessorNaming, - List elements) { - List presenceCheckMethods = new LinkedList(); + private TypeMirror getReturnType(ExecutableElement executableElement) { + return getWithinContext( executableElement ).getReturnType(); + } - for ( Accessor method : elements ) { - if ( accessorNaming.isPresenceCheckMethod( method ) ) { - presenceCheckMethods.add( (ExecutableElementAccessor) method ); - } - } + public List fieldsIn(List accessors, BiFunction creator) { + return accessors.stream() + .filter( Fields::isFieldAccessor ) + .map( variableElement -> creator.apply( variableElement, getWithinContext( variableElement ) ) ) + .collect( Collectors.toCollection( LinkedList::new ) ); + } - return presenceCheckMethods; + public List presenceCheckMethodsIn(List elements) { + return elements.stream() + .filter( accessorNaming::isPresenceCheckMethod ) + .collect( Collectors.toCollection( LinkedList::new ) ); } - public static List setterMethodsIn(AccessorNamingUtils accessorNaming, List elements) { - List setterMethods = new LinkedList(); + public List setterMethodsIn(List elements) { + return elements.stream() + .filter( accessorNaming::isSetterMethod ) + .map( method -> new ElementAccessor( method, getFirstParameter( method ), SETTER ) ) + .collect( Collectors.toCollection( LinkedList::new ) ); + } - for ( Accessor method : elements ) { - if ( accessorNaming.isSetterMethod( method ) ) { - setterMethods.add( method ); - } - } - return setterMethods; + private TypeMirror getFirstParameter(ExecutableElement executableElement) { + return first( getWithinContext( executableElement ).getParameterTypes() ); } - public static List adderMethodsIn(AccessorNamingUtils accessorNaming, List elements) { - List adderMethods = new LinkedList(); + private ExecutableType getWithinContext( ExecutableElement executableElement ) { + return (ExecutableType) typeUtils.asMemberOf( (DeclaredType) typeMirror, executableElement ); + } - for ( Accessor method : elements ) { - if ( accessorNaming.isAdderMethod( method ) ) { - adderMethods.add( method ); - } - } + private TypeMirror getWithinContext( VariableElement variableElement ) { + return typeUtils.asMemberOf( (DeclaredType) typeMirror, variableElement ); + } - return adderMethods; + public List adderMethodsIn(List elements) { + return elements.stream() + .filter( accessorNaming::isAdderMethod ) + .map( method -> new ElementAccessor( method, getFirstParameter( method ), ADDER ) ) + .collect( Collectors.toCollection( LinkedList::new ) ); } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/FormattingMessager.java b/processor/src/main/java/org/mapstruct/ap/internal/util/FormattingMessager.java index 5de057365e..6f3b1dc7a9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/FormattingMessager.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/FormattingMessager.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; @@ -52,10 +39,10 @@ public interface FormattingMessager { /** * Prints a message of the specified kind at the location of the - * annotation mirror of the annotated element. + * annotation positionHint of the annotated element. * * @param e the annotated element - * @param a the annotation to use as a position hint + * @param a the annotation to use as a position hint (can be null) * @param msg the message * @param args Arguments referenced by the format specifiers in the format string. If there are more arguments * than format specifiers, the extra arguments are ignored @@ -65,7 +52,7 @@ public interface FormattingMessager { /** * Prints a message of the specified kind at the location of the - * annotation value inside the annotation mirror of the annotated + * annotation value inside the annotation positionHint of the annotated * element. * * @param e the annotated element @@ -80,4 +67,14 @@ void printMessage(Element e, AnnotationValue v, Message msg, Object... args); + + /** + * Just log as plain note + * @param level nesting level + * @param log the log message + * @param args the arguments + */ + void note(int level, Message log, Object... args); + + boolean isErroneous(); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/FreeBuilderConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/FreeBuilderConstants.java new file mode 100644 index 0000000000..e7ae4d63d4 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/FreeBuilderConstants.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +/** + * Helper for holding FreeBuilder FQN. + * + * @author Filip Hrisafov + */ +public class FreeBuilderConstants { + + public static final String FREE_BUILDER_FQN = "org.inferred.freebuilder.FreeBuilder"; + + private FreeBuilderConstants() { + + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/IgnoreJRERequirement.java b/processor/src/main/java/org/mapstruct/ap/internal/util/IgnoreJRERequirement.java new file mode 100644 index 0000000000..565ebcce12 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/IgnoreJRERequirement.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.CLASS) +@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE }) +public @interface IgnoreJRERequirement { +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/ImmutablesConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/ImmutablesConstants.java index 164888beb8..4e670d17d0 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/ImmutablesConstants.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/ImmutablesConstants.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JSpecifyConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JSpecifyConstants.java new file mode 100644 index 0000000000..7836e0deba --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JSpecifyConstants.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +/** + * Helper holding constants for working with JSpecify null annotations. + * + * @author Filip Hrisafov + */ +public final class JSpecifyConstants { + + /** + * Fully qualified name of {@code org.jspecify.annotations.Nullable}. + */ + public static final String NULLABLE_FQN = "org.jspecify.annotations.Nullable"; + + /** + * Fully qualified name of {@code org.jspecify.annotations.NonNull}. + */ + public static final String NON_NULL_FQN = "org.jspecify.annotations.NonNull"; + + /** + * Fully qualified name of {@code org.jspecify.annotations.NullMarked}. Its presence on an + * element (or an enclosing element closer than any {@code @NullUnmarked} one) means unannotated + * types in that scope are effectively {@code @NonNull}. + */ + public static final String NULL_MARKED_FQN = "org.jspecify.annotations.NullMarked"; + + /** + * Fully qualified name of {@code org.jspecify.annotations.NullUnmarked}. Its presence on an + * element (or an enclosing element closer than any {@code @NullMarked} one) reverts the scope + * back to unknown nullability. + */ + public static final String NULL_UNMARKED_FQN = "org.jspecify.annotations.NullUnmarked"; + + private JSpecifyConstants() { + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JavaCollectionConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JavaCollectionConstants.java new file mode 100644 index 0000000000..68d556c542 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JavaCollectionConstants.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +/** + * Helper holding Java collections full qualified class names for conversion registration, + * to achieve Java compatibility. + * + * @author Cause Chung + */ +public final class JavaCollectionConstants { + public static final String SEQUENCED_MAP_FQN = "java.util.SequencedMap"; + public static final String SEQUENCED_SET_FQN = "java.util.SequencedSet"; + + private JavaCollectionConstants() { + + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JavaStreamConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JavaStreamConstants.java index b532bcf564..acd63abcd7 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/JavaStreamConstants.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JavaStreamConstants.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; @@ -26,10 +13,6 @@ public final class JavaStreamConstants { public static final String STREAM_FQN = "java.util.stream.Stream"; - public static final String COLLECTORS_FQN = "java.util.stream.Collectors"; - public static final String STREAM_SUPPORT_FQN = "java.util.stream.StreamSupport"; - public static final String OPTIONAL_FQN = "java.util.Optional"; - public static final String FUNCTION_FQN = "java.util.function.Function"; private JavaStreamConstants() { } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JavaTimeConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JavaTimeConstants.java deleted file mode 100644 index a83c52a6f8..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/JavaTimeConstants.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util; - -/** - * Helper holding Java time full qualified class names for conversion registration - */ -public final class JavaTimeConstants { - - public static final String ZONED_DATE_TIME_FQN = "java.time.ZonedDateTime"; - public static final String ZONE_OFFSET_FQN = "java.time.ZoneOffset"; - public static final String ZONE_ID_FQN = "java.time.ZoneId"; - - public static final String LOCAL_DATE_TIME_FQN = "java.time.LocalDateTime"; - public static final String LOCAL_DATE_FQN = "java.time.LocalDate"; - public static final String LOCAL_TIME_FQN = "java.time.LocalTime"; - - public static final String DATE_TIME_FORMATTER_FQN = "java.time.format.DateTimeFormatter"; - - private JavaTimeConstants() { - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JavacElementUtilsDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JavacElementUtilsDecorator.java new file mode 100644 index 0000000000..fa0e46171b --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JavacElementUtilsDecorator.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.TypeElement; + +public class JavacElementUtilsDecorator extends AbstractElementUtilsDecorator { + + JavacElementUtilsDecorator(ProcessingEnvironment processingEnv, TypeElement mapperElement) { + super( processingEnv, mapperElement ); + } + + @Override + protected TypeElement replaceTypeElementIfNecessary(TypeElement element) { + return element; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JavacTypeUtilsDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JavacTypeUtilsDecorator.java new file mode 100644 index 0000000000..8b3454e87e --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JavacTypeUtilsDecorator.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import javax.annotation.processing.ProcessingEnvironment; + +public class JavacTypeUtilsDecorator extends AbstractTypeUtilsDecorator { + + JavacTypeUtilsDecorator(ProcessingEnvironment processingEnv) { + super( processingEnv ); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java index c7c9e6c55c..c89877062e 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JaxbConstants.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; @@ -23,19 +10,10 @@ */ public final class JaxbConstants { - public static final String JAXB_ELEMENT_FQN = "javax.xml.bind.JAXBElement"; - private static final boolean IS_JAXB_ELEMENT_PRESENT = ClassUtils.isPresent( - JAXB_ELEMENT_FQN, - JaxbConstants.class.getClassLoader() - ); + public static final String JAVAX_JAXB_ELEMENT_FQN = "javax.xml.bind.JAXBElement"; + public static final String JAKARTA_JAXB_ELEMENT_FQN = "jakarta.xml.bind.JAXBElement"; private JaxbConstants() { } - /** - * @return {@code true} if {@link javax.xml.bind.JAXBElement} is present, {@code false} otherwise - */ - public static boolean isJaxbElementPresent() { - return IS_JAXB_ELEMENT_PRESENT; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/JodaTimeConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/JodaTimeConstants.java index 0e889cff4f..5300f1bf91 100755 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/JodaTimeConstants.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/JodaTimeConstants.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java b/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java deleted file mode 100644 index d7bb90260b..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/MapperConfiguration.java +++ /dev/null @@ -1,265 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util; - -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; - -import javax.lang.model.element.AnnotationMirror; -import javax.lang.model.element.Element; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; - -import org.mapstruct.ap.internal.option.Options; -import org.mapstruct.ap.internal.prism.BuilderPrism; -import org.mapstruct.ap.internal.prism.CollectionMappingStrategyPrism; -import org.mapstruct.ap.internal.prism.InjectionStrategyPrism; -import org.mapstruct.ap.internal.prism.MapperConfigPrism; -import org.mapstruct.ap.internal.prism.MapperPrism; -import org.mapstruct.ap.internal.prism.MappingInheritanceStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueCheckStrategyPrism; -import org.mapstruct.ap.internal.prism.NullValueMappingStrategyPrism; -import org.mapstruct.ap.internal.prism.ReportingPolicyPrism; - -/** - * Provides an aggregated view to the settings given via {@link org.mapstruct.Mapper} and - * {@link org.mapstruct.MapperConfig} for a specific mapper class. - *

      - * Settings given via {@code Mapper} will generally take precedence over settings inherited from a referenced config - * class. The lists of referenced mappers given via {@link org.mapstruct.Mapper#uses()} and - * {@link org.mapstruct.MapperConfig#uses() } will be merged. - * - * @author Sjaak Derksen - */ -public class MapperConfiguration { - - private final MapperPrism mapperPrism; - private final MapperConfigPrism mapperConfigPrism; - private final DeclaredType config; - - public static MapperConfiguration getInstanceOn(Element e) { - return new MapperConfiguration( MapperPrism.getInstanceOn( e ) ); - } - - private MapperConfiguration(MapperPrism mapperPrism) { - this.mapperPrism = mapperPrism; - - if ( mapperPrism.values.config() != null ) { - // TODO #737 Only a declared type makes sense here; Validate and raise graceful error; - // Also validate that @MapperConfig is present - this.config = (DeclaredType) mapperPrism.config(); - this.mapperConfigPrism = MapperConfigPrism.getInstanceOn( config.asElement() ); - } - else { - this.config = null; - this.mapperConfigPrism = null; - } - } - - public String implementationName() { - if ( mapperConfigPrism != null && mapperPrism.values.implementationName() == null ) { - return mapperConfigPrism.implementationName(); - } - else { - return mapperPrism.implementationName(); - } - } - - public String implementationPackage() { - if ( mapperConfigPrism != null && mapperPrism.values.implementationPackage() == null ) { - return mapperConfigPrism.implementationPackage(); - } - else { - return mapperPrism.implementationPackage(); - } - } - - public Set uses() { - Set uses = new LinkedHashSet(); - - for ( TypeMirror usedMapperType : mapperPrism.uses() ) { - // TODO #737 Only declared type make sense here; Validate and raise graceful error; - uses.add( (DeclaredType) usedMapperType ); - } - - if ( mapperConfigPrism != null ) { - for ( TypeMirror usedMapperType : mapperConfigPrism.uses() ) { - // TODO #737 Only declared type make sense here; Validate and raise graceful error; - uses.add( (DeclaredType) usedMapperType ); - } - } - - return uses; - } - - public List imports() { - return mapperPrism.imports(); - } - - public ReportingPolicyPrism unmappedTargetPolicy(Options options) { - if ( mapperPrism.values.unmappedTargetPolicy() != null ) { - return ReportingPolicyPrism.valueOf( mapperPrism.unmappedTargetPolicy() ); - } - - if ( mapperConfigPrism != null && mapperConfigPrism.values.unmappedTargetPolicy() != null ) { - return ReportingPolicyPrism.valueOf( mapperConfigPrism.unmappedTargetPolicy() ); - } - - if ( options.getUnmappedTargetPolicy() != null ) { - return options.getUnmappedTargetPolicy(); - } - - // fall back to default defined in the annotation - return ReportingPolicyPrism.valueOf( mapperPrism.unmappedTargetPolicy() ); - } - - public ReportingPolicyPrism unmappedSourcePolicy() { - if ( mapperPrism.values.unmappedSourcePolicy() != null ) { - return ReportingPolicyPrism.valueOf( mapperPrism.unmappedSourcePolicy() ); - } - - if ( mapperConfigPrism != null && mapperConfigPrism.values.unmappedSourcePolicy() != null ) { - return ReportingPolicyPrism.valueOf( mapperConfigPrism.unmappedSourcePolicy() ); - } - - // fall back to default defined in the annotation - return ReportingPolicyPrism.valueOf( mapperPrism.unmappedSourcePolicy() ); - } - - public CollectionMappingStrategyPrism getCollectionMappingStrategy() { - if ( mapperConfigPrism != null && mapperPrism.values.collectionMappingStrategy() == null ) { - return CollectionMappingStrategyPrism.valueOf( mapperConfigPrism.collectionMappingStrategy() ); - } - else { - return CollectionMappingStrategyPrism.valueOf( mapperPrism.collectionMappingStrategy() ); - } - } - - public MappingInheritanceStrategyPrism getMappingInheritanceStrategy() { - if ( mapperConfigPrism != null && mapperPrism.values.mappingInheritanceStrategy() == null ) { - return MappingInheritanceStrategyPrism.valueOf( mapperConfigPrism.mappingInheritanceStrategy() ); - } - else { - return MappingInheritanceStrategyPrism.valueOf( mapperPrism.mappingInheritanceStrategy() ); - } - } - - public NullValueCheckStrategyPrism getNullValueCheckStrategy() { - if ( mapperConfigPrism != null && mapperPrism.values.nullValueCheckStrategy() == null ) { - return NullValueCheckStrategyPrism.valueOf( mapperConfigPrism.nullValueCheckStrategy() ); - } - else { - return NullValueCheckStrategyPrism.valueOf( mapperPrism.nullValueCheckStrategy() ); - } - } - - public InjectionStrategyPrism getInjectionStrategy() { - if ( mapperConfigPrism != null && mapperPrism.values.injectionStrategy() == null ) { - return InjectionStrategyPrism.valueOf( mapperConfigPrism.injectionStrategy() ); - } - else { - return InjectionStrategyPrism.valueOf( mapperPrism.injectionStrategy() ); - } - } - - public NullValueMappingStrategyPrism getNullValueMappingStrategy() { - if ( mapperConfigPrism != null && mapperPrism.values.nullValueMappingStrategy() == null ) { - return NullValueMappingStrategyPrism.valueOf( mapperConfigPrism.nullValueMappingStrategy() ); - } - else { - return NullValueMappingStrategyPrism.valueOf( mapperPrism.nullValueMappingStrategy() ); - } - } - - public boolean isMapToDefault(NullValueMappingStrategyPrism mapNullToDefault) { - - // check on method level - if ( mapNullToDefault != null ) { - return mapNullToDefault == NullValueMappingStrategyPrism.RETURN_DEFAULT; - } - - return isMapToDefaultOnMapperAndMappingConfigLevel(); - - } - - private boolean isMapToDefaultOnMapperAndMappingConfigLevel() { - final NullValueMappingStrategyPrism strategy; - if ( mapperConfigPrism != null && mapperPrism.values.nullValueMappingStrategy() == null ) { - strategy = NullValueMappingStrategyPrism.valueOf( mapperConfigPrism.nullValueMappingStrategy() ); - } - else { - strategy = NullValueMappingStrategyPrism.valueOf( mapperPrism.nullValueMappingStrategy() ); - } - - return NullValueMappingStrategyPrism.RETURN_DEFAULT == strategy; - } - - public String componentModel(Options options) { - if ( mapperPrism.values.componentModel() != null ) { - return mapperPrism.componentModel(); - } - - if ( mapperConfigPrism != null && mapperConfigPrism.values.componentModel() != null ) { - return mapperConfigPrism.componentModel(); - } - - if ( options.getDefaultComponentModel() != null ) { - return options.getDefaultComponentModel(); - } - - return mapperPrism.componentModel(); // fall back to default defined in the annotation - } - - public boolean isDisableSubMappingMethodsGeneration() { - if ( mapperPrism.disableSubMappingMethodsGeneration() ) { - return mapperPrism.disableSubMappingMethodsGeneration(); - } - - if ( mapperConfigPrism != null && mapperConfigPrism.disableSubMappingMethodsGeneration() ) { - return mapperConfigPrism.disableSubMappingMethodsGeneration(); - } - - return mapperPrism.disableSubMappingMethodsGeneration(); // fall back to default defined in the annotation - } - - public BuilderPrism getBuilderPrism() { - if ( mapperPrism.values.builder() != null ) { - return mapperPrism.builder(); - } - else if ( mapperConfigPrism != null && mapperConfigPrism.values.builder() != null ) { - return mapperConfigPrism.builder(); - } - else { - return null; - } - } - - public DeclaredType config() { - return config; - } - - public boolean isValid() { - return mapperPrism.isValid; - } - - public AnnotationMirror getAnnotationMirror() { - return mapperPrism.mirror; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java index de257c2e6e..acac07b4b3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Message.java @@ -1,25 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; import javax.tools.Diagnostic; +import static org.mapstruct.ap.internal.util.MessageConstants.FAQ_AMBIGUOUS_URL; +import static org.mapstruct.ap.internal.util.MessageConstants.FAQ_QUALIFIER_URL; + /** * A message used in warnings/errors raised by the annotation processor. * @@ -28,11 +18,19 @@ public enum Message { // CHECKSTYLE:OFF - BEANMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy', 'resultType' and 'qualifiedBy' are undefined in @BeanMapping, define at least one of them." ), + PROCESSING_NOTE( "processing: %s.", Diagnostic.Kind.NOTE ), + CONFIG_NOTE( "applying mapper configuration: %s.", Diagnostic.Kind.NOTE ), + MESSAGE_MOVED_TO_MAPPER_ERROR( "%s Occured at '%s' in '%s'." ), + MESSAGE_MOVED_TO_MAPPER_WARNING( "%s Occured at '%s' in '%s'.", Diagnostic.Kind.WARNING ), + + BEANMAPPING_CREATE_NOTE( "creating bean mapping method implementation for %s.", Diagnostic.Kind.NOTE ), + BEANMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy', 'nullValuePropertyMappingStrategy', 'resultType' and 'qualifiedBy' are undefined in @BeanMapping, define at least one of them." ), BEANMAPPING_NOT_ASSIGNABLE( "%s not assignable to: %s." ), BEANMAPPING_ABSTRACT( "The result type %s may not be an abstract class nor interface." ), BEANMAPPING_UNKNOWN_PROPERTY_IN_RESULTTYPE( "Unknown property \"%s\" in result type %s. Did you mean \"%s\"?" ), + BEANMAPPING_UNKNOWN_PROPERTY_IN_TYPE( "Unknown property \"%s\" in type %s for target name \"%s\". Did you mean \"%s\"?" ), BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_RESULTTYPE( "Property \"%s\" has no write accessor in %s." ), + BEANMAPPING_PROPERTY_HAS_NO_WRITE_ACCESSOR_IN_TYPE( "Property \"%s\" has no write accessor in %s for target name \"%s\"." ), BEANMAPPING_SEVERAL_POSSIBLE_SOURCES( "Several possible source properties for target property \"%s\"." ), BEANMAPPING_SEVERAL_POSSIBLE_TARGET_ACCESSORS( "Found several matching getters for property \"%s\"." ), BEANMAPPING_UNMAPPED_TARGETS_WARNING( "Unmapped target %s.", Diagnostic.Kind.WARNING ), @@ -41,11 +39,26 @@ public enum Message { BEANMAPPING_UNMAPPED_FORGED_TARGETS_ERROR( "Unmapped target %s. Mapping from %s to %s." ), BEANMAPPING_UNMAPPED_SOURCES_WARNING( "Unmapped source %s.", Diagnostic.Kind.WARNING ), BEANMAPPING_UNMAPPED_SOURCES_ERROR( "Unmapped source %s." ), + BEANMAPPING_UNMAPPED_FORGED_SOURCES_WARNING( "Unmapped source %s. Mapping from %s to %s.", Diagnostic.Kind.WARNING ), + BEANMAPPING_UNMAPPED_FORGED_SOURCES_ERROR( "Unmapped source %s. Mapping from %s to %s." ), + BEANMAPPING_MISSING_IGNORED_SOURCES_ERROR( "Ignored unknown source %s." ), + BEANMAPPING_REDUNDANT_IGNORED_SOURCES_ERROR( "Source %s mapped despite being listed in ignoreUnmappedSourceProperties." ), + BEANMAPPING_REDUNDANT_IGNORED_SOURCES_WARNING( "Source %s mapped despite being listed in ignoreUnmappedSourceProperties.", Diagnostic.Kind.WARNING ), BEANMAPPING_CYCLE_BETWEEN_PROPERTIES( "Cycle(s) between properties given via dependsOn(): %s." ), BEANMAPPING_UNKNOWN_PROPERTY_IN_DEPENDS_ON( "\"%s\" is no property of the method return type." ), + BEANMAPPING_IGNORE_BY_DEFAULT_WITH_MAPPING_TARGET_THIS( "Using @BeanMapping( ignoreByDefault = true ) with @Mapping( target = \".\", ... ) is not allowed. You'll need to explicitly ignore the target properties that should be ignored instead." ), + BEANMAPPING_UNKNOWN_PROPERTY_IN_IGNORED("No property named \"%s\" exists in @Ignored for target type \"%s\". Did you mean \"%s\"?"), + + CONDITION_MISSING_APPLIES_TO_STRATEGY("'appliesTo' has to have at least one value in @Condition" ), + CONDITION_SOURCE_PARAMETERS_INVALID_PARAMETER("Parameter \"%s\" cannot be used with the ConditionStrategy#SOURCE_PARAMETERS. Only source and @Context parameters are allowed for conditions applicable to source parameters." ), + CONDITION_PROPERTIES_INVALID_PARAMETER("Parameter \"%s\" cannot be used with the ConditionStrategy#PROPERTIES. Only source, @Context, @MappingTarget, @TargetType, @TargetPropertyName and @SourcePropertyName parameters are allowed for conditions applicable to properties." ), + PROPERTYMAPPING_MAPPING_NOTE( "mapping property: %s to: %s.", Diagnostic.Kind.NOTE ), + PROPERTYMAPPING_CREATE_NOTE( "creating property mapping: %s.", Diagnostic.Kind.NOTE ), + PROPERTYMAPPING_SELECT_NOTE( "selecting property mapping: %s.", Diagnostic.Kind.NOTE ), PROPERTYMAPPING_MAPPING_NOT_FOUND( "Can't map %s to \"%s %s\". Consider to declare/implement a mapping method: \"%s map(%s value)\"." ), - PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND( "Can't map %s to %s. Consider to implement a mapping method: \"%s map(%s value)\"." ), + PROPERTYMAPPING_FORGED_MAPPING_WITH_HISTORY_NOT_FOUND( "No target bean properties found: can't map %s to \"%s %s\". Consider to declare/implement a mapping method: \"%s map(%s value)\"." ), + PROPERTYMAPPING_FORGED_MAPPING_NOT_FOUND( "No target bean properties found: can't map %s to %s. Consider to implement a mapping method: \"%s map(%s value)\"." ), PROPERTYMAPPING_DUPLICATE_TARGETS( "Target property \"%s\" must not be mapped more than once." ), PROPERTYMAPPING_EMPTY_TARGET( "Target must not be empty in @Mapping." ), PROPERTYMAPPING_SOURCE_AND_CONSTANT_BOTH_DEFINED( "Source and constant are both defined in @Mapping, either define a source or a constant." ), @@ -55,27 +68,63 @@ public enum Message { PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_VALUE_BOTH_DEFINED( "Expression and default value are both defined in @Mapping, either define a defaultValue or an expression." ), PROPERTYMAPPING_CONSTANT_AND_DEFAULT_VALUE_BOTH_DEFINED( "Constant and default value are both defined in @Mapping, either define a defaultValue or a constant." ), PROPERTYMAPPING_EXPRESSION_AND_DEFAULT_EXPRESSION_BOTH_DEFINED( "Expression and default expression are both defined in @Mapping, either define an expression or a default expression." ), + PROPERTYMAPPING_EXPRESSION_AND_CONDITION_EXPRESSION_BOTH_DEFINED( "Expression and condition expression are both defined in @Mapping, either define an expression or a condition expression." ), PROPERTYMAPPING_CONSTANT_AND_DEFAULT_EXPRESSION_BOTH_DEFINED( "Constant and default expression are both defined in @Mapping, either define a constant or a default expression." ), + PROPERTYMAPPING_CONSTANT_AND_CONDITION_EXPRESSION_BOTH_DEFINED( "Constant and condition expression are both defined in @Mapping, either define a constant or a condition expression." ), PROPERTYMAPPING_DEFAULT_VALUE_AND_DEFAULT_EXPRESSION_BOTH_DEFINED( "Default value and default expression are both defined in @Mapping, either define a default value or a default expression." ), + PROPERTYMAPPING_DEFAULT_VALUE_AND_NVPMS( "Default value and nullValuePropertyMappingStrategy are both defined in @Mapping, either define a defaultValue or an nullValuePropertyMappingStrategy." ), + PROPERTYMAPPING_EXPRESSION_VALUE_AND_NVPMS( "Expression and nullValuePropertyMappingStrategy are both defined in @Mapping, either define an expression or an nullValuePropertyMappingStrategy." ), + PROPERTYMAPPING_CONSTANT_VALUE_AND_NVPMS( "Constant and nullValuePropertyMappingStrategy are both defined in @Mapping, either define a constant or an nullValuePropertyMappingStrategy." ), + PROPERTYMAPPING_DEFAULT_EXPERSSION_AND_NVPMS( "DefaultExpression and nullValuePropertyMappingStrategy are both defined in @Mapping, either define a defaultExpression or an nullValuePropertyMappingStrategy." ), + PROPERTYMAPPING_IGNORE_AND_NVPMS( "Ignore and nullValuePropertyMappingStrategy are both defined in @Mapping, either define ignore or an nullValuePropertyMappingStrategy." ), + PROPERTYMAPPING_TARGET_THIS_AND_IGNORE( "Using @Mapping( target = \".\", ignore = true ) is not allowed. You need to use @BeanMapping( ignoreByDefault = true ) if you would like to ignore all non explicitly mapped target properties." ), + PROPERTYMAPPING_TARGET_THIS_NO_SOURCE( "Using @Mapping( target = \".\") requires a source property. Expression or constant cannot be used as a source."), + PROPERTYMAPPING_EXPRESSION_AND_QUALIFIER_BOTH_DEFINED("Expression and a qualifier both defined in @Mapping, either define an expression or a qualifier."), PROPERTYMAPPING_INVALID_EXPRESSION( "Value for expression must be given in the form \"java()\"." ), PROPERTYMAPPING_INVALID_DEFAULT_EXPRESSION( "Value for default expression must be given in the form \"java()\"." ), + PROPERTYMAPPING_INVALID_CONDITION_EXPRESSION( "Value for condition expression must be given in the form \"java()\"." ), PROPERTYMAPPING_INVALID_PARAMETER_NAME( "Method has no source parameter named \"%s\". Method source parameters are: \"%s\"." ), PROPERTYMAPPING_NO_PROPERTY_IN_PARAMETER( "The type of parameter \"%s\" has no property named \"%s\"." ), PROPERTYMAPPING_INVALID_PROPERTY_NAME( "No property named \"%s\" exists in source parameter(s). Did you mean \"%s\"?" ), + PROPERTYMAPPING_INVALID_PROPERTY_NAME_SOURCE_HAS_NO_PROPERTIES( "No property named \"%s\" exists in source parameter(s). Type \"%s\" has no properties." ), PROPERTYMAPPING_NO_PRESENCE_CHECKER_FOR_SOURCE_TYPE( "Using custom source value presence checking strategy, but no presence checker found for %s in source type." ), PROPERTYMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ), PROPERTYMAPPING_NO_WRITE_ACCESSOR_FOR_TARGET_TYPE( "No write accessor found for property \"%s\" in target type." ), PROPERTYMAPPING_WHITESPACE_TRIMMED( "The property named \"%s\" has whitespaces, using trimmed property \"%s\" instead.", Diagnostic.Kind.WARNING ), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PROPERTY_FROM_TARGET("The type of parameter \"%s\" has no property named \"%s\". Please define the source property explicitly."), + PROPERTYMAPPING_CANNOT_DETERMINE_SOURCE_PARAMETER_FROM_TARGET("No property named \"%s\" exists in source parameter(s). Please define the source explicitly."), + PROPERTYMAPPING_NO_SUITABLE_COLLECTION_OR_MAP_CONSTRUCTOR( "%s does not have an accessible copy or no-args constructor." ), + PROPERTYMAPPING_NO_ACCESSIBLE_PARAMETERLESS_CONSTRUCTOR( "%s does not have an accessible parameterless constructor. Either change the nullValuePropertyMappingStrategy or define a defaultValue or a defaultExpression." ), + PROPERTYMAPPING_EXPRESSION_AND_CONDITION_QUALIFIED_BY_NAME_BOTH_DEFINED( "Expression and condition qualified by name are both defined in @Mapping, either define an expression or a condition qualified by name." ), + PROPERTYMAPPING_TARGET_HAS_NO_TARGET_PROPERTIES( "No target property found for target \"%s\".", Diagnostic.Kind.WARNING ), + PROPERTYMAPPING_NULLABLE_SOURCE_TO_NON_NULL_CONSTRUCTOR_PARAM( "Can't map potentially nullable source property \"%s\" to @NonNull constructor parameter \"%s\". Consider adding a defaultValue or defaultExpression." ), + PROPERTYMAPPING_JSPECIFY_SKIP_NULL_CHECK_NON_NULL_SOURCE( "JSpecify skipping null check for property \"%s\": source is @NonNull.", Diagnostic.Kind.NOTE ), + PROPERTYMAPPING_JSPECIFY_ADD_NULL_CHECK( "JSpecify adding null check for property \"%s\": source=%s, target=%s.", Diagnostic.Kind.NOTE ), + PROPERTYMAPPING_JSPECIFY_SKIP_NULL_CHECK( "JSpecify skipping null check for property \"%s\": source=%s, target=%s.", Diagnostic.Kind.NOTE ), + PROPERTYMAPPING_JSPECIFY_SKIP_METHOD_GUARD_NON_NULL_PARAM( "JSpecify skipping method-level null guard for property \"%s\": parameter is @NonNull.", Diagnostic.Kind.NOTE ), + MAPPING_METHOD_JSPECIFY_FORCE_RETURN_DEFAULT( "JSpecify forcing NullValueMappingStrategy.RETURN_DEFAULT for method \"%s\": return type is @NonNull.", Diagnostic.Kind.NOTE ), - CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map \"%s %s\" to \"%s %s\"." ), - CONSTANTMAPPING_MAPPING_NOT_FOUND_WITH_DETAILS( "Can't map \"%s %s\" to \"%s %s\". Reason: %s." ), + CONVERSION_LOSSY_WARNING( "%s has a possibly lossy conversion from %s to %s.", Diagnostic.Kind.WARNING ), + CONVERSION_LOSSY_ERROR( "Can't map %s. It has a possibly lossy conversion from %s to %s." ), + + CONSTANTMAPPING_MAPPING_NOT_FOUND( "Can't map %s to \"%s %s\"." ), + CONSTANTMAPPING_MAPPING_NOT_FOUND_WITH_DETAILS( "Can't map %s to \"%s %s\". Reason: %s." ), CONSTANTMAPPING_NO_READ_ACCESSOR_FOR_TARGET_TYPE( "No read accessor found for property \"%s\" in target type." ), CONSTANTMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s for property \"%s\"." ), + MAPMAPPING_CREATE_NOTE( "creating map mapping method implementation for %s.", Diagnostic.Kind.NOTE ), MAPMAPPING_KEY_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source key type to target key type." ), MAPMAPPING_VALUE_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source value type to target value type." ), MAPMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy', 'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', 'valueDateFormat', 'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, define at least one of them." ), + MAPMAPPING_SELECT_KEY_NOTE( "selecting key mapping: %s.", Diagnostic.Kind.NOTE ), + MAPMAPPING_SELECT_VALUE_NOTE( "selecting value mapping: %s.", Diagnostic.Kind.NOTE ), + MAPMAPPING_CREATE_KEY_NOTE( "creating key mapping: %s.", Diagnostic.Kind.NOTE ), + MAPMAPPING_CREATE_VALUE_NOTE( "creating value mapping: %s.", Diagnostic.Kind.NOTE ), + STREAMMAPPING_CREATE_NOTE( "creating stream mapping method implementation for %s.", Diagnostic.Kind.NOTE ), + ITERABLEMAPPING_CREATE_NOTE( "creating iterable mapping method implementation for %s.", Diagnostic.Kind.NOTE ), + ITERABLEMAPPING_SELECT_ELEMENT_NOTE( "selecting element mapping: %s.", Diagnostic.Kind.NOTE ), + ITERABLEMAPPING_CREATE_ELEMENT_NOTE( "creating element mapping: %s.", Diagnostic.Kind.NOTE ), ITERABLEMAPPING_MAPPING_NOT_FOUND( "No implementation can be generated for this method. Found no method nor implicit conversion for mapping source element type into target element type." ), ITERABLEMAPPING_NO_ELEMENTS( "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are undefined in @IterableMapping, define at least one of them." ), @@ -84,21 +133,47 @@ public enum Message { ENUMMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s." ), ENUMMAPPING_UNDEFINED_TARGET( "A target constant must be specified for mappings of an enum mapping method." ), ENUMMAPPING_UNMAPPED_SOURCES( "The following constants from the source enum have no corresponding constant in the target enum and must be be mapped via adding additional mappings: %s." ), - ENUMMAPPING_DEPRECATED( "Mapping of Enums via @Mapping is going to be removed in future versions of MapStruct. Please use @ValueMapping instead!", Diagnostic.Kind.WARNING ), + ENUMMAPPING_REMOVED( "Mapping of Enums via @Mapping is removed. Please use @ValueMapping instead!" ), + ENUMMAPPING_INCORRECT_TRANSFORMATION_STRATEGY( "There is no registered EnumTransformationStrategy for '%s'. Registered strategies are: %s." ), + ENUMMAPPING_MISSING_CONFIGURATION( "Configuration has to be defined when strategy is defined." ), + ENUMMAPPING_NO_ELEMENTS( "'nameTransformationStrategy', 'configuration' and 'unexpectedValueMappingException' are undefined in @EnumMapping, define at least one of them." ), + ENUMMAPPING_ILLEGAL_TRANSFORMATION( "Illegal transformation for '%s' EnumTransformationStrategy. Error: '%s'." ), + + SUBCLASSMAPPING_DOUBLE_SOURCE_SUBCLASS( "Subclass '%s' is already defined as a source." ), + SUBCLASSMAPPING_ILLEGAL_SUBCLASS( "Class '%s' is not a subclass of '%s'." ), + SUBCLASSMAPPING_NO_VALID_SUPERCLASS( "Could not find a parameter that is a superclass for '%s'." ), + SUBCLASSMAPPING_UPDATE_METHODS_NOT_SUPPORTED( "SubclassMapping annotation can not be used for update methods." ), + SUBCLASSMAPPING_ILLOGICAL_ORDER( "SubclassMapping annotation for '%s' found after '%s', but all '%s' objects are also instances of '%s'.", Diagnostic.Kind.WARNING ), + + LIFECYCLEMETHOD_AMBIGUOUS_PARAMETERS( "Lifecycle method has multiple matching parameters (e. g. same type), in this case please ensure to name the parameters in the lifecycle and mapping method identical. This lifecycle method will not be used for the mapping method '%s'.", Diagnostic.Kind.WARNING), DECORATOR_NO_SUBTYPE( "Specified decorator type is no subtype of the annotated mapper type." ), DECORATOR_CONSTRUCTOR( "Specified decorator type has no default constructor nor a constructor with a single parameter accepting the decorated mapper type." ), + JAVADOC_NO_ELEMENTS( "'value', 'authors', 'deprecated' and 'since' are undefined in @Javadoc, define at least one of them." ), + + GENERAL_CANNOT_IMPLEMENT_PRIVATE_MAPPER("Cannot create an implementation for mapper %s, because it is a private %s."), GENERAL_NO_IMPLEMENTATION( "No implementation type is registered for return type %s." ), GENERAL_ABSTRACT_RETURN_TYPE( "The return type %s is an abstract class or interface. Provide a non abstract / non interface result type or a factory method." ), - GENERAL_AMBIGIOUS_MAPPING_METHOD( "Ambiguous mapping methods found for mapping %s to %s: %s." ), - GENERAL_AMBIGIOUS_FACTORY_METHOD( "Ambiguous factory methods found for creating %s: %s." ), + GENERAL_AMBIGUOUS_MAPPING_METHOD( "Ambiguous mapping methods found for mapping %s to %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ), + GENERAL_AMBIGUOUS_FACTORY_METHOD( "Ambiguous factory methods found for creating %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ), + GENERAL_AMBIGUOUS_PRESENCE_CHECK_METHOD( "Ambiguous presence check methods found for checking %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ), + GENERAL_AMBIGUOUS_SOURCE_PARAMETER_CHECK_METHOD( "Ambiguous source parameter check methods found for checking %s: %s. See " + FAQ_AMBIGUOUS_URL + " for more info." ), + GENERAL_AMBIGUOUS_CONSTRUCTORS( "Ambiguous constructors found for creating %s: %s. Either declare parameterless constructor or annotate the default constructor with an annotation named @Default." ), + GENERAL_CONSTRUCTOR_PROPERTIES_NOT_MATCHING_PARAMETERS( "Incorrect @ConstructorProperties for %s. The size of the @ConstructorProperties does not match the number of constructor parameters" ), GENERAL_UNSUPPORTED_DATE_FORMAT_CHECK( "No dateFormat check is supported for types %s, %s" ), GENERAL_VALID_DATE( "Given date format \"%s\" is valid.", Diagnostic.Kind.NOTE ), GENERAL_INVALID_DATE( "Given date format \"%s\" is invalid. Message: \"%s\"." ), GENERAL_JODA_NOT_ON_CLASSPATH( "Cannot validate Joda dateformat, no Joda on classpath. Consider adding Joda to the annotation processorpath.", Diagnostic.Kind.WARNING ), GENERAL_NOT_ALL_FORGED_CREATED( "Internal Error in creation of Forged Methods, it was expected all Forged Methods to finished with creation, but %s did not" ), - GENERAL_NO_SUITABLE_CONSTRUCTOR( "%s does not have an accessible parameterless constructor." ), + GENERAL_NO_SUITABLE_CONSTRUCTOR( "%s does not have an accessible constructor." ), + GENERAL_NO_QUALIFYING_METHOD_ANNOTATION( "Qualifier error. No method found annotated with: [ %s ]. See " + FAQ_QUALIFIER_URL + " for more info." ), + GENERAL_NO_QUALIFYING_METHOD_NAMED( "Qualifier error. No method found annotated with @Named#value: [ %s ]. See " + FAQ_QUALIFIER_URL + " for more info." ), + GENERAL_NO_QUALIFYING_METHOD_COMBINED( "Qualifier error. No method found annotated with @Named#value: [ %s ], annotated with [ %s ]. See " + FAQ_QUALIFIER_URL + " for more info." ), + + GENERAL_AMBIGUOUS_MAPPING_METHODY_METHODX( "Ambiguous 2step methods found, mapping %s to %s. Found methodY( methodX ( parameter ) ): %s." ), + GENERAL_AMBIGUOUS_MAPPING_CONVERSIONY_METHODX( "Ambiguous 2step methods found, mapping %s to %s. Found conversionY( methodX ( parameter ) ): %s." ), + GENERAL_AMBIGUOUS_MAPPING_METHODY_CONVERSIONX( "Ambiguous 2step methods found, mapping %s to %s. Found methodY( conversionX ( parameter ) ): %s." ), BUILDER_MORE_THAN_ONE_BUILDER_CREATION_METHOD( "More than one builder creation method for \"%s\". Found methods: \"%s\". Builder will not be used. Consider implementing a custom BuilderProvider SPI.", Diagnostic.Kind.WARNING ), BUILDER_NO_BUILD_METHOD_FOUND("No build method \"%s\" found in \"%s\" for \"%s\". Found methods: \"%s\".", Diagnostic.Kind.ERROR ), @@ -107,19 +182,23 @@ public enum Message { RETRIEVAL_NO_INPUT_ARGS( "Can't generate mapping method with no input arguments." ), RETRIEVAL_DUPLICATE_MAPPING_TARGETS( "Can't generate mapping method with more than one @MappingTarget parameter." ), RETRIEVAL_VOID_MAPPING_METHOD( "Can't generate mapping method with return type void." ), - RETRIEVAL_NON_ASSIGNABLE_RESULTTYPE( "The result type is not assignable to the the return type." ), - RETRIEVAL_ITERABLE_TO_NON_ITERABLE( "Can't generate mapping method from iterable type to non-iterable type." ), + RETRIEVAL_NON_ASSIGNABLE_RESULTTYPE( "The result type is not assignable to the return type." ), + RETRIEVAL_ITERABLE_TO_NON_ITERABLE( "Can't generate mapping method from iterable type from java stdlib to non-iterable type." ), RETRIEVAL_MAPPING_HAS_TARGET_TYPE_PARAMETER( "Can't generate mapping method that has a parameter annotated with @TargetType." ), - RETRIEVAL_NON_ITERABLE_TO_ITERABLE( "Can't generate mapping method from non-iterable type to iterable type." ), + RETRIEVAL_NON_ITERABLE_TO_ITERABLE( "Can't generate mapping method from non-iterable type to iterable type from java stdlib." ), + RETRIEVAL_NON_ITERABLE_TO_ARRAY( "Can't generate mapping method from non-iterable type to array." ), RETRIEVAL_PRIMITIVE_PARAMETER( "Can't generate mapping method with primitive parameter type." ), RETRIEVAL_PRIMITIVE_RETURN( "Can't generate mapping method with primitive return type." ), - RETRIEVAL_ENUM_TO_NON_ENUM( "Can't generate mapping method from enum type to non-enum type." ), - RETRIEVAL_NON_ENUM_TO_ENUM( "Can't generate mapping method from non-enum type to enum type." ), RETRIEVAL_TYPE_VAR_SOURCE( "Can't generate mapping method for a generic type variable source." ), RETRIEVAL_TYPE_VAR_RESULT( "Can't generate mapping method for a generic type variable target." ), RETRIEVAL_WILDCARD_SUPER_BOUND_SOURCE( "Can't generate mapping method for a wildcard super bound source." ), RETRIEVAL_WILDCARD_EXTENDS_BOUND_RESULT( "Can't generate mapping method for a wildcard extends bound result." ), RETRIEVAL_CONTEXT_PARAMS_WITH_SAME_TYPE( "The types of @Context parameters must be unique." ), + RETRIEVAL_MAPPER_USES_CYCLE( "The mapper %s is referenced itself in Mapper#uses.", Diagnostic.Kind.WARNING ), + RETRIEVAL_AFTER_METHOD_NOT_IMPLEMENTED( "@AfterMapping can only be applied to an implemented method." ), + RETRIEVAL_BEFORE_METHOD_NOT_IMPLEMENTED( "@BeforeMapping can only be applied to an implemented method." ), + RETRIEVAL_SOURCE_PROPERTY_NAME_WRONG_TYPE( "@SourcePropertyName can only by applied to a String parameter." ), + RETRIEVAL_TARGET_PROPERTY_NAME_WRONG_TYPE( "@TargetPropertyName can only by applied to a String parameter." ), INHERITINVERSECONFIGURATION_DUPLICATES( "Several matching inverse methods exist: %s(). Specify a name explicitly." ), INHERITINVERSECONFIGURATION_INVALID_NAME( "None of the candidates %s() matches given name: \"%s\"." ), @@ -133,11 +212,33 @@ public enum Message { INHERITINVERSECONFIGURATION_MULTIPLE_PROTOTYPE_METHODS_MATCH( "More than one configuration prototype method is applicable. Use @InheritInverseConfiguration to select one of them explicitly: %s." ), INHERITCONFIGURATION_CYCLE( "Cycle detected while evaluating inherited configurations. Inheritance path: %s" ), + VALUEMAPPING_CREATE_NOTE( "creating value mapping method implementation for %s.", Diagnostic.Kind.NOTE ), VALUEMAPPING_DUPLICATE_SOURCE( "Source value mapping: \"%s\" cannot be mapped more than once." ), VALUEMAPPING_ANY_AREADY_DEFINED( "Source = \"\" or \"\" can only be used once." ), - VALUE_MAPPING_UNMAPPED_SOURCES( "The following constants from the %s enum have no corresponding constant in the %s enum and must be be mapped via adding additional mappings: %s." ), - VALUEMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s." ); + VALUEMAPPING_UNMAPPED_SOURCES( "The following constants from the %s enum have no corresponding constant in the %s enum and must be be mapped via adding additional mappings: %s." ), + VALUEMAPPING_ANY_REMAINING_FOR_NON_ENUM( "Source = \"\" can only be used on targets of type enum and not for %s." ), + VALUEMAPPING_ANY_REMAINING_OR_UNMAPPED_MISSING( "Source = \"\" or \"\" is advisable for mapping of type String to an enum type.", Diagnostic.Kind.WARNING ), + VALUEMAPPING_NON_EXISTING_CONSTANT_FROM_SPI( "Constant %s doesn't exist in enum type %s. Constant was returned from EnumMappingStrategy: %s"), + VALUEMAPPING_NON_EXISTING_CONSTANT( "Constant %s doesn't exist in enum type %s." ), + VALUEMAPPING_THROW_EXCEPTION_SOURCE( "Source = \"\" is not allowed. Target = \"\" can only be used." ), + + MAPTOBEANMAPPING_WRONG_KEY_TYPE( "The Map parameter \"%s\" cannot be used for property mapping. It must be typed with Map but it was typed with %s.", Diagnostic.Kind.WARNING ), + MAPTOBEANMAPPING_RAW_MAP( "The Map parameter \"%s\" cannot be used for property mapping. It must be typed with Map but it was raw.", Diagnostic.Kind.WARNING ), + ANNOTATE_WITH_MISSING_REQUIRED_PARAMETER( "Parameter \"%s\" is required for annotation \"%s\"." ), + ANNOTATE_WITH_UNKNOWN_PARAMETER( "Unknown parameter \"%s\" for annotation \"%s\". Did you mean \"%s\"?" ), + ANNOTATE_WITH_DUPLICATE_PARAMETER( "Parameter \"%s\" must not be defined more than once." ), + ANNOTATE_WITH_WRONG_PARAMETER( "Parameter \"%s\" is not of type \"%s\" but of type \"%s\" for annotation \"%s\"." ), + ANNOTATE_WITH_TOO_MANY_VALUE_TYPES( "Parameter \"%s\" has too many value types supplied, type \"%s\" is expected for annotation \"%s\"." ), + ANNOTATE_WITH_PARAMETER_ARRAY_NOT_EXPECTED( "Parameter \"%s\" does not accept multiple values for annotation \"%s\"." ), + ANNOTATE_WITH_NOT_ALLOWED_ON_CLASS( "Annotation \"%s\" is not allowed on classes." ), + ANNOTATE_WITH_NOT_ALLOWED_ON_METHODS( "Annotation \"%s\" is not allowed on methods." ), + ANNOTATE_WITH_ENUM_VALUE_DOES_NOT_EXIST( "Enum \"%s\" does not have value \"%s\"." ), + ANNOTATE_WITH_ENUM_CLASS_NOT_DEFINED( "enumClass needs to be defined when using enums." ), + ANNOTATE_WITH_ENUMS_NOT_DEFINED( "enums needs to be defined when using enumClass." ), + ANNOTATE_WITH_ANNOTATION_IS_NOT_REPEATABLE( "Annotation \"%s\" is not repeatable." ), + ANNOTATE_WITH_DUPLICATE( "Annotation \"%s\" is already present with the same elements configuration.", Diagnostic.Kind.WARNING ), + ; // CHECKSTYLE:ON private final String description; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/MessageConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/MessageConstants.java new file mode 100644 index 0000000000..6b4603af19 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/MessageConstants.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +public final class MessageConstants { + + public static final String AND = " and "; + public static final String FAQ_QUALIFIER_URL = "https://mapstruct.org/faq/#qualifier"; + public static final String FAQ_AMBIGUOUS_URL = "https://mapstruct.org/faq/#ambiguous"; + + private MessageConstants() { + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/MetaAnnotations.java b/processor/src/main/java/org/mapstruct/ap/internal/util/MetaAnnotations.java new file mode 100644 index 0000000000..96768daf56 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/MetaAnnotations.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; + +import org.mapstruct.tools.gem.Gem; + +/** + * A base helper class that provides utility methods for working with meta annotations. + * + * @param The type of the processed annotation + * @param The type of the underlying holder for the processed annotation + * + * @author Filip Hrisafov + */ +public abstract class MetaAnnotations { + + private static final String JAVA_LANG_ANNOTATION_PGK = "java.lang.annotation"; + + private final ElementUtils elementUtils; + private final String annotationFqn; + + protected MetaAnnotations(ElementUtils elementUtils, String annotationFqn) { + this.elementUtils = elementUtils; + this.annotationFqn = annotationFqn; + } + + /** + * Retrieves the processed annotations. + * + * @param source The source element of interest + * @return The processed annotations for the given element + */ + public Set getProcessedAnnotations(Element source) { + return getValues( source, source, new LinkedHashSet<>(), new HashSet<>() ); + } + + protected abstract G instanceOn(Element element); + + protected abstract void addInstance(G gem, Element source, Set values); + + /** + * Retrieves the processed annotations. + * + * @param source The source element of interest + * @param element Element of interest: method, or (meta) annotation + * @param values the set of values found so far + * @param handledElements The collection of already handled elements to handle recursion correctly. + * @return The processed annotations for the given element + */ + private Set getValues(Element source, Element element, Set values, Set handledElements) { + for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { + Element annotationElement = annotationMirror.getAnnotationType().asElement(); + if ( isAnnotation( annotationElement, annotationFqn ) ) { + G gem = instanceOn( element ); + addInstance( gem, source, values ); + } + else if ( isNotJavaAnnotation( element ) && !handledElements.contains( annotationElement ) ) { + handledElements.add( annotationElement ); + getValues( source, annotationElement, values, handledElements ); + } + } + return values; + } + + private boolean isNotJavaAnnotation(Element element) { + if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) { + return !elementUtils.getPackageOf( element ).getQualifiedName().contentEquals( JAVA_LANG_ANNOTATION_PGK ); + } + return true; + } + + private boolean isAnnotation(Element element, String annotationFqn) { + if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) { + return ( (TypeElement) element ).getQualifiedName().contentEquals( annotationFqn ); + } + + return false; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/NativeTypes.java b/processor/src/main/java/org/mapstruct/ap/internal/util/NativeTypes.java index 85c56060dd..ff01ae0ef3 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/NativeTypes.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/NativeTypes.java @@ -1,31 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Collections; +import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.regex.Pattern; +import javax.lang.model.type.TypeKind; /** * Provides functionality around the Java primitive data types and their wrapper types. They are considered native. @@ -36,9 +25,12 @@ public class NativeTypes { private static final Map, Class> WRAPPER_TO_PRIMITIVE_TYPES; private static final Map, Class> PRIMITIVE_TO_WRAPPER_TYPES; - private static final Set> NUMBER_TYPES = new HashSet>(); + private static final Set> NUMBER_TYPES = new HashSet<>(); + private static final Map TYPE_KIND_NAME = new EnumMap<>( TypeKind.class ); private static final Map ANALYZERS; + private static final Map NARROWING_LUT; + private static final Pattern PTRN_HEX = Pattern.compile( "^0[x|X].*" ); private static final Pattern PTRN_OCT = Pattern.compile( "^0_*[0-7].*" ); private static final Pattern PTRN_BIN = Pattern.compile( "^0[b|B].*" ); @@ -175,7 +167,6 @@ void removeAndValidateIntegerLiteralSuffix() { /** * Double suffix forbidden for float. * - * @param isFloat */ void removeAndValidateFloatingPointLiteralSuffix() { boolean endsWithLSuffix = PTRN_LONG.matcher( val ).find(); @@ -183,7 +174,7 @@ void removeAndValidateFloatingPointLiteralSuffix() { boolean endsWithDSuffix = PTRN_DOUBLE.matcher( val ).find(); // error handling if ( isFloat && endsWithDSuffix ) { - throw new NumberFormatException( "Assiging double to a float" ); + throw new NumberFormatException( "Assigning double to a float" ); } // remove suffix if ( endsWithLSuffix || endsWithFSuffix || endsWithDSuffix ) { @@ -279,11 +270,11 @@ public void validate(String s) { @Override void parse(String val, int radix) { - Double d = Double.parseDouble( radix == 16 ? "0x" + val : val ); + double d = Double.parseDouble( radix == 16 ? "0x" + val : val ); if ( doubleHasBecomeZero( d ) ) { throw new NumberFormatException( "floating point number too small" ); } - if ( d.isInfinite() ) { + if ( Double.isInfinite( d ) ) { throw new NumberFormatException( "infinitive is not allowed" ); } } @@ -293,7 +284,7 @@ void parse(String val, int radix) { @Override public Class getLiteral() { - return float.class; + return double.class; } } @@ -306,11 +297,11 @@ public void validate(String s) { NumberRepresentation br = new NumberRepresentation( s, false, false, true ) { @Override void parse(String val, int radix) { - Float f = Float.parseFloat( radix == 16 ? "0x" + val : val ); + float f = Float.parseFloat( radix == 16 ? "0x" + val : val ); if ( doubleHasBecomeZero( f ) ) { throw new NumberFormatException( "floating point number too small" ); } - if ( f.isInfinite() ) { + if ( Float.isInfinite( f ) ) { throw new NumberFormatException( "infinitive is not allowed" ); } } @@ -372,7 +363,7 @@ else if ( new BigInteger( val, radix ).bitLength() > 64 ) { @Override public Class getLiteral() { - return int.class; + return long.class; } } @@ -400,7 +391,7 @@ private NativeTypes() { } static { - Map, Class> tmp = new HashMap, Class>(); + Map, Class> tmp = new HashMap<>(); tmp.put( Byte.class, byte.class ); tmp.put( Short.class, short.class ); tmp.put( Integer.class, int.class ); @@ -412,7 +403,7 @@ private NativeTypes() { WRAPPER_TO_PRIMITIVE_TYPES = Collections.unmodifiableMap( tmp ); - tmp = new HashMap, Class>(); + tmp = new HashMap<>(); tmp.put( byte.class, Byte.class ); tmp.put( short.class, Short.class ); tmp.put( int.class, Integer.class ); @@ -439,7 +430,7 @@ private NativeTypes() { NUMBER_TYPES.add( BigInteger.class ); NUMBER_TYPES.add( BigDecimal.class ); - Map tmp2 = new HashMap(); + Map tmp2 = new HashMap<>(); tmp2.put( boolean.class.getCanonicalName(), new BooleanAnalyzer() ); tmp2.put( Boolean.class.getCanonicalName(), new BooleanAnalyzer() ); tmp2.put( char.class.getCanonicalName(), new CharAnalyzer() ); @@ -459,6 +450,32 @@ private NativeTypes() { ANALYZERS = Collections.unmodifiableMap( tmp2 ); + TYPE_KIND_NAME.put( TypeKind.BOOLEAN, "boolean" ); + TYPE_KIND_NAME.put( TypeKind.BYTE, "byte" ); + TYPE_KIND_NAME.put( TypeKind.SHORT, "short" ); + TYPE_KIND_NAME.put( TypeKind.INT, "int" ); + TYPE_KIND_NAME.put( TypeKind.LONG, "long" ); + TYPE_KIND_NAME.put( TypeKind.CHAR, "char" ); + TYPE_KIND_NAME.put( TypeKind.FLOAT, "float" ); + TYPE_KIND_NAME.put( TypeKind.DOUBLE, "double" ); + + Map tmp3 = new HashMap<>( ); + tmp3.put( byte.class.getName(), 1 ); + tmp3.put( Byte.class.getName(), 1 ); + tmp3.put( short.class.getName(), 2 ); + tmp3.put( Short.class.getName(), 2 ); + tmp3.put( int.class.getName(), 3 ); + tmp3.put( Integer.class.getName(), 3 ); + tmp3.put( long.class.getName(), 4 ); + tmp3.put( Long.class.getName(), 4 ); + tmp3.put( float.class.getName(), 5 ); + tmp3.put( Float.class.getName(), 5 ); + tmp3.put( double.class.getName(), 6 ); + tmp3.put( Double.class.getName(), 6 ); + tmp3.put( BigInteger.class.getName(), 50 ); + tmp3.put( BigDecimal.class.getName(), 51 ); + tmp3.put( String.class.getName(), 51 ); + NARROWING_LUT = Collections.unmodifiableMap( tmp3 ); } public static Class getWrapperType(Class clazz) { @@ -506,4 +523,29 @@ public static Class getLiteral(String className, String literal) { } return result; } + + /** + * The name that should be used for the {@code typeKind}. + * Should be used in order to get the name of a primitive type + * + * @param typeKind the type kind + * + * @return the name that should be used for the {@code typeKind} + */ + public static String getName(TypeKind typeKind) { + return TYPE_KIND_NAME.get( typeKind ); + } + + public static boolean isNarrowing( String sourceFQN, String targetFQN ) { + + boolean isNarrowing = false; + + Integer sourcePosition = NARROWING_LUT.get( sourceFQN ); + Integer targetPosition = NARROWING_LUT.get( targetFQN ); + + if ( sourcePosition != null && targetPosition != null ) { + isNarrowing = ( targetPosition - sourcePosition < 0 ); + } + return isNarrowing; + } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Nouns.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Nouns.java index 1db29bb06a..ccd7a1e863 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Nouns.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Nouns.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/NullabilityResolver.java b/processor/src/main/java/org/mapstruct/ap/internal/util/NullabilityResolver.java new file mode 100644 index 0000000000..768886cb95 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/NullabilityResolver.java @@ -0,0 +1,257 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.util.List; +import java.util.function.BooleanSupplier; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; + +/** + * Resolver for JSpecify nullness annotations on elements, used to decide whether a null + * check is required for a source-to-target property mapping. + *

      + * A single instance is created per annotation-processor run and carries the + * {@link #enabled} flag derived from the {@code mapstruct.disableJSpecify} option. When + * disabled, all public entry points short-circuit to {@link Nullability#UNKNOWN} / + * {@code null}, which causes downstream callers to fall back to the pre-JSpecify + * {@code NullValueCheckStrategy}-based behavior. + * + * @author Filip Hrisafov + */ +public class NullabilityResolver { + + /** + * Represents the effective nullability of a source or target element. + */ + public enum Nullability { + /** + * The element is effectively non-null — either directly annotated {@code @NonNull}, + * or within a {@code @NullMarked} scope without a closer {@code @NullUnmarked} or + * {@code @Nullable} override. + */ + NON_NULL, + /** + * The element is explicitly annotated {@code @Nullable}. + */ + NULLABLE, + /** + * Nullability is unspecified — no annotation applies and the element is not within + * an applicable {@code @NullMarked} scope (or JSpecify support is disabled). + */ + UNKNOWN + } + + private final boolean enabled; + + public NullabilityResolver(boolean enabled) { + this.enabled = enabled; + } + + /** + * Determines the nullability of an accessor element based on JSpecify annotations. + *

      + * For getter methods ({@link ExecutableElement}), this checks the return type's annotations + * since JSpecify annotations are {@code TYPE_USE} annotations placed on the return type. + * For setter parameters ({@link VariableElement}), this checks the parameter type's annotations. + * For fields ({@link VariableElement}), this checks the field type's annotations. + *

      + * If no direct annotation is found, the method walks the enclosing element chain looking + * for a method-level {@code @NullMarked} / {@code @NullUnmarked}. If nothing is found there + * either, {@code enclosingTypeNullMarked} is consulted — when it returns {@code true}, + * unannotated types are effectively {@code @NonNull}. The supplier is invoked at most once. + *

      + * When this resolver is disabled, {@link Nullability#UNKNOWN} is returned without any + * inspection — the supplier is not invoked. + * + * @param element the accessor element to inspect (getter method, setter parameter, or field); + * may be {@code null} in which case {@link Nullability#UNKNOWN} is returned + * @param enclosingTypeNullMarked supplier for whether the enclosing bean type is in a + * {@code @NullMarked} scope; must be non-{@code null} + * @return the nullability state + */ + public Nullability getNullability(Element element, BooleanSupplier enclosingTypeNullMarked) { + if ( !enabled || element == null ) { + return Nullability.UNKNOWN; + } + + // JSpecify annotations are TYPE_USE annotations. + // For getters: annotation is on the return type + // For setter parameters / fields: annotation is on the variable type + if ( element instanceof ExecutableElement ) { + // Getter method — check the return type annotations + TypeMirror returnType = ( (ExecutableElement) element ).getReturnType(); + Nullability result = getNullabilityFromTypeMirror( returnType ); + if ( result != Nullability.UNKNOWN ) { + return result; + } + } + else if ( element instanceof VariableElement ) { + // Setter parameter or field — check the variable type annotations + TypeMirror type = element.asType(); + Nullability result = getNullabilityFromTypeMirror( type ); + if ( result != Nullability.UNKNOWN ) { + return result; + } + } + + // Fallback: check declaration-level annotation mirrors. Some compilers (notably ECJ) + // surface JSpecify TYPE_USE annotations on the element rather than the type mirror. + Nullability fromElement = getNullabilityFromAnnotationMirrors( element.getAnnotationMirrors() ); + if ( fromElement != Nullability.UNKNOWN ) { + return fromElement; + } + + // Walk enclosing elements up to the declaring type to honor method-level + // @NullMarked / @NullUnmarked (e.g. a @NullUnmarked method inside a @NullMarked class + // must revert unannotated types back to unknown nullability). + Boolean elementScope = resolveElementScope( element ); + if ( elementScope != null ) { + return elementScope ? Nullability.NON_NULL : Nullability.UNKNOWN; + } + + // No element-level scope — consult the enclosing bean type's @NullMarked scope. + if ( enclosingTypeNullMarked.getAsBoolean() ) { + return Nullability.NON_NULL; + } + + return Nullability.UNKNOWN; + } + + /** + * Determines the nullability of a write-accessor element — either a setter method or a field. + *

      + * For setter methods ({@link ExecutableElement}) the nullability annotation lives on the + * parameter type, not on the method itself, so the first parameter's nullability is returned. + * For fields (or any other element type) the element's own type nullability is returned. + * + * @param element the write-accessor element (setter or field); may be + * {@code null} in which case {@link Nullability#UNKNOWN} is returned + * @param enclosingTypeNullMarked supplier for whether the enclosing bean type is in a + * {@code @NullMarked} scope; must be non-{@code null} + * @return the nullability state of the setter's parameter or of the field + */ + public Nullability getSetterNullability(Element element, BooleanSupplier enclosingTypeNullMarked) { + if ( !enabled ) { + return Nullability.UNKNOWN; + } + if ( element instanceof ExecutableElement ) { + List parameters = ( (ExecutableElement) element ).getParameters(); + if ( parameters.isEmpty() ) { + // A zero-parameter method is not a valid write accessor. Falling through to + // getNullability would inspect the return type, which is meaningless here. + return Nullability.UNKNOWN; + } + return getNullability( parameters.get( 0 ), enclosingTypeNullMarked ); + } + // Field or other write accessor: consult the element's own type nullability. + return getNullability( element, enclosingTypeNullMarked ); + } + + /** + * Determines whether a null check is required for a property mapping based on JSpecify annotations + * on the source and target elements. + *

      + * Only returns a non-null decision for the clear-cut cases: + * source {@code @NonNull} (skip check) or target {@code @NonNull} (always check). + * All other cases return {@code null} to defer to the existing {@code NullValueCheckStrategy}. + * + * @param sourceNullability the nullability of the source (getter return type / parameter) + * @param targetNullability the nullability of the target (setter parameter / field) + * @return {@code Boolean.TRUE} if a null check is needed, {@code Boolean.FALSE} if it should be skipped, + * or {@code null} if JSpecify annotations are not present and the existing strategy should be used + */ + public Boolean requiresNullCheck(Nullability sourceNullability, Nullability targetNullability) { + if ( !enabled ) { + return null; + } + if ( sourceNullability == Nullability.NON_NULL ) { + // Source is guaranteed non-null, no null check needed + return Boolean.FALSE; + } + if ( targetNullability == Nullability.NON_NULL ) { + // Target requires non-null: always check (regardless of source annotation) + return Boolean.TRUE; + } + // All other cases: defer to existing NullValueCheckStrategy + return null; + } + + /** + * Walks from {@code element} up to (but not including) its declaring {@link TypeElement}, + * checking for {@code @NullMarked} / {@code @NullUnmarked} on intermediate elements + * (e.g. the enclosing method of a parameter, or the element itself for a field / getter). + * + * @return {@code TRUE} when a closer {@code @NullMarked} is found, {@code FALSE} when a + * closer {@code @NullUnmarked} is found, or {@code null} when neither is present before + * the declaring type is reached (leaving the bean-type scope to decide). + */ + private static Boolean resolveElementScope(Element element) { + Element current = element; + while ( current != null && !isTypeElement( current ) ) { + Boolean scope = findScopeAnnotation( current ); + if ( scope != null ) { + return scope; + } + current = current.getEnclosingElement(); + } + return null; + } + + private static boolean isTypeElement(Element element) { + ElementKind kind = element.getKind(); + return kind.isClass() || kind.isInterface(); + } + + private static Boolean findScopeAnnotation(Element element) { + for ( AnnotationMirror mirror : element.getAnnotationMirrors() ) { + Element annotationElement = mirror.getAnnotationType().asElement(); + if ( !( annotationElement instanceof TypeElement ) ) { + continue; + } + String fqn = ( (TypeElement) annotationElement ).getQualifiedName().toString(); + if ( JSpecifyConstants.NULL_MARKED_FQN.equals( fqn ) ) { + return Boolean.TRUE; + } + if ( JSpecifyConstants.NULL_UNMARKED_FQN.equals( fqn ) ) { + return Boolean.FALSE; + } + } + return null; + } + + private static Nullability getNullabilityFromTypeMirror(TypeMirror typeMirror) { + if ( typeMirror == null ) { + return Nullability.UNKNOWN; + } + return getNullabilityFromAnnotationMirrors( typeMirror.getAnnotationMirrors() ); + } + + private static Nullability getNullabilityFromAnnotationMirrors( + List annotationMirrors) { + for ( AnnotationMirror mirror : annotationMirrors ) { + Element annotationElement = mirror.getAnnotationType().asElement(); + if ( !( annotationElement instanceof TypeElement ) ) { + // Defensive: during incremental builds the annotation may be an ErrorType + // whose element is not a TypeElement. Skip instead of failing with a CCE. + continue; + } + String fqn = ( (TypeElement) annotationElement ).getQualifiedName().toString(); + if ( JSpecifyConstants.NON_NULL_FQN.equals( fqn ) ) { + return Nullability.NON_NULL; + } + if ( JSpecifyConstants.NULLABLE_FQN.equals( fqn ) ) { + return Nullability.NULLABLE; + } + } + return Nullability.UNKNOWN; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/RepeatableAnnotations.java b/processor/src/main/java/org/mapstruct/ap/internal/util/RepeatableAnnotations.java new file mode 100644 index 0000000000..76126bf488 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/RepeatableAnnotations.java @@ -0,0 +1,126 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.Set; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.TypeElement; + +import org.mapstruct.tools.gem.Gem; + +/** + * A base helper class that provides utility methods for working with repeatable annotations. + * + * @param The singular annotation type + * @param The multiple annotation type + * @param The underlying holder for the processed annotations + * + * @author Ben Zegveld + */ +public abstract class RepeatableAnnotations { + private static final String JAVA_LANG_ANNOTATION_PGK = "java.lang.annotation"; + private static final String ORG_MAPSTRUCT_PKG = "org.mapstruct"; + + private ElementUtils elementUtils; + private final String singularFqn; + private final String multipleFqn; + + protected RepeatableAnnotations(ElementUtils elementUtils, String singularFqn, String multipleFqn) { + this.elementUtils = elementUtils; + this.singularFqn = singularFqn; + this.multipleFqn = multipleFqn; + } + + /** + * @param element the element on which the Gem needs to be found + * @return the Gem found on the element. + */ + protected abstract SINGULAR singularInstanceOn(Element element); + + /** + * @param element the element on which the Gems needs to be found + * @return the Gems found on the element. + */ + protected abstract MULTIPLE multipleInstanceOn(Element element); + + /** + * @param gem the annotation gem to be processed + * @param source the source element where the request originated from + * @param mappings the collection of completed processing + */ + protected abstract void addInstance(SINGULAR gem, Element source, Set mappings); + + /** + * @param gems the annotation gems to be processed + * @param source the source element where the request originated from + * @param mappings the collection of completed processing + */ + protected abstract void addInstances(MULTIPLE gems, Element source, Set mappings); + + /** + * Retrieves the processed annotations. + * + * @param source The source element of interest + * @return The processed annotations for the given element + */ + public Set getProcessedAnnotations(Element source) { + return getMappings( source, source, new LinkedHashSet<>(), new HashSet<>() ); + } + + /** + * Retrieves the processed annotations. + * + * @param source The source element of interest + * @param element Element of interest: method, or (meta) annotation + * @param mappingOptions LinkedSet of mappings found so far + * @param handledElements The collection of already handled elements to handle recursion correctly. + * @return The processed annotations for the given element + */ + private Set getMappings(Element source, Element element, + LinkedHashSet mappingOptions, + Set handledElements) { + + for ( AnnotationMirror annotationMirror : element.getAnnotationMirrors() ) { + Element lElement = annotationMirror.getAnnotationType().asElement(); + if ( isAnnotation( lElement, singularFqn ) ) { + // although getInstanceOn does a search on annotation mirrors, the order is preserved + SINGULAR mapping = singularInstanceOn( element ); + addInstance( mapping, source, mappingOptions ); + } + else if ( isAnnotation( lElement, multipleFqn ) ) { + // although getInstanceOn does a search on annotation mirrors, the order is preserved + MULTIPLE mappings = multipleInstanceOn( element ); + addInstances( mappings, source, mappingOptions ); + } + else if ( !isAnnotationInPackage( lElement, JAVA_LANG_ANNOTATION_PGK ) + && !isAnnotationInPackage( lElement, ORG_MAPSTRUCT_PKG ) + && !handledElements.contains( lElement ) ) { + // recur over annotation mirrors + handledElements.add( lElement ); + getMappings( source, lElement, mappingOptions, handledElements ); + } + } + return mappingOptions; + } + + private boolean isAnnotationInPackage(Element element, String packageFQN) { + if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) { + return packageFQN.equals( elementUtils.getPackageOf( element ).getQualifiedName().toString() ); + } + return false; + } + + private boolean isAnnotation(Element element, String annotationFQN) { + if ( ElementKind.ANNOTATION_TYPE == element.getKind() ) { + return annotationFQN.equals( ( (TypeElement) element ).getQualifiedName().toString() ); + } + return false; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/RoundContext.java b/processor/src/main/java/org/mapstruct/ap/internal/util/RoundContext.java index c06a335440..6106fdc1b0 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/RoundContext.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/RoundContext.java @@ -1,26 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; import java.util.HashSet; import java.util.Set; - import javax.lang.model.type.TypeMirror; import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; @@ -37,7 +23,7 @@ public class RoundContext { public RoundContext(AnnotationProcessorContext annotationProcessorContext) { this.annotationProcessorContext = annotationProcessorContext; - this.clearedTypes = new HashSet(); + this.clearedTypes = new HashSet<>(); } public AnnotationProcessorContext getAnnotationProcessorContext() { @@ -54,7 +40,7 @@ public void addTypeReadyForProcessing(TypeMirror type) { /** * Whether the given type has been found to be ready for further processing or not. This is the case if the type's - * hierarchy is complete (no super-types need to be generated by other processors) an no processors have signaled + * hierarchy is complete (no super-types need to be generated by other processors) and no processors have signaled * the intention to amend the given type. * * @param type the typed to be checked for its readiness diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java index f70ce2a56b..292512ff80 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Services.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; @@ -31,6 +18,10 @@ public class Services { private Services() { } + public static Iterable all(Class serviceType) { + return ServiceLoader.load( serviceType, Services.class.getClassLoader() ); + } + public static T get(Class serviceType, T defaultValue) { Iterator services = ServiceLoader.load( serviceType, Services.class.getClassLoader() ).iterator(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java b/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java index a14e4d8ada..61ca397b8d 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/Strings.java @@ -1,31 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; -import static org.mapstruct.ap.internal.util.Collections.asSet; - import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Locale; import java.util.Set; +import static org.mapstruct.ap.internal.util.Collections.asSet; + /** * Helper class for dealing with strings. * @@ -86,6 +73,8 @@ public class Strings { "while" ); + private static final char UNDERSCORE = '_'; + private Strings() { } @@ -140,8 +129,12 @@ public static boolean isEmpty(String string) { return string == null || string.isEmpty(); } - public static String getSaveVariableName(String name, String... existingVariableNames) { - return getSaveVariableName( name, Arrays.asList( existingVariableNames ) ); + public static boolean isNotEmpty(String string) { + return !isEmpty( string ); + } + + public static String getSafeVariableName(String name, String... existingVariableNames) { + return getSafeVariableName( name, Arrays.asList( existingVariableNames ) ); } /** @@ -154,11 +147,11 @@ public static String getSaveVariableName(String name, String... existingVariable * @return a variable name based on the given original name, not conflicting with any of the given other names or * any Java keyword; starting with a lower-case letter */ - public static String getSaveVariableName(String name, Collection existingVariableNames) { + public static String getSafeVariableName(String name, Collection existingVariableNames) { name = decapitalize( sanitizeIdentifierName( name ) ); name = joinAndCamelize( extractParts( name ) ); - Set conflictingNames = new HashSet( KEYWORDS ); + Set conflictingNames = new HashSet<>( KEYWORDS ); conflictingNames.addAll( existingVariableNames ); if ( !conflictingNames.contains( name ) ) { @@ -166,12 +159,12 @@ public static String getSaveVariableName(String name, Collection existin } int c = 1; - String seperator = Character.isDigit( name.charAt( name.length() - 1 ) ) ? "_" : ""; - while ( conflictingNames.contains( name + seperator + c ) ) { + String separator = Character.isDigit( name.charAt( name.length() - 1 ) ) ? "_" : ""; + while ( conflictingNames.contains( name + separator + c ) ) { c++; } - return name + seperator + c; + return name + separator + c; } /** @@ -179,7 +172,35 @@ public static String getSaveVariableName(String name, Collection existin * @return the identifier without any characters that are not allowed as part of a Java identifier. */ public static String sanitizeIdentifierName(String identifier) { - return identifier.replace( "[]", "Array" ); + if ( identifier != null && identifier.length() > 0 ) { + + int firstAlphabeticIndex = 0; + while ( firstAlphabeticIndex < identifier.length() && + ( identifier.charAt( firstAlphabeticIndex ) == UNDERSCORE || + Character.isDigit( identifier.charAt( firstAlphabeticIndex ) ) ) ) { + firstAlphabeticIndex++; + } + + if ( firstAlphabeticIndex < identifier.length() ) { + // If it is not consisted of only underscores + String firstAlphaString = identifier.substring( firstAlphabeticIndex ).replace( "[]", "Array" ); + + StringBuilder sb = new StringBuilder( firstAlphaString.length() ); + for ( int i = 0; i < firstAlphaString.length(); i++ ) { + int codePoint = firstAlphaString.codePointAt( i ); + if ( Character.isJavaIdentifierPart( codePoint ) || codePoint == '.' ) { + sb.appendCodePoint( codePoint ); + } + else { + sb.append( '_' ); + } + } + return sb.toString(); + } + + return identifier.replace( "[]", "Array" ); + } + return identifier; } /** diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/TypeUtils.java b/processor/src/main/java/org/mapstruct/ap/internal/util/TypeUtils.java new file mode 100644 index 0000000000..926cd5eef8 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/TypeUtils.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; + +import org.mapstruct.ap.internal.version.VersionInformation; + +public interface TypeUtils extends Types { + + static TypeUtils create(ProcessingEnvironment processingEnvironment, VersionInformation info ) { + if ( info.isEclipseJDTCompiler() ) { + return new EclipseTypeUtilsDecorator( processingEnvironment ); + } + else { + return new JavacTypeUtilsDecorator( processingEnvironment ); + } + } + + boolean isSubtypeErased(TypeMirror t1, TypeMirror t2); +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/ValueProvider.java b/processor/src/main/java/org/mapstruct/ap/internal/util/ValueProvider.java deleted file mode 100644 index 19b28293ac..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/ValueProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util; - -import org.mapstruct.ap.internal.util.accessor.Accessor; - -/** - * This a wrapper class which provides the value that needs to be used in the models. - * - * It is used to provide the read value for a difference kind of {@link Accessor}. - * - * @author Filip Hrisafov - */ -public class ValueProvider { - - private final String value; - - private ValueProvider(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return value; - } - - /** - * Creates a {@link ValueProvider} from the provided {@code accessor}. The base value is - * {@link Accessor#getSimpleName()}. If the {@code accessor} is for an executable, then {@code ()} is - * appended. - * - * @param accessor that provides the value - * - * @return a {@link ValueProvider} tha provides a read value for the {@code accessor} - */ - public static ValueProvider of(Accessor accessor) { - if ( accessor == null ) { - return null; - } - String value = accessor.getSimpleName().toString(); - if ( accessor.getExecutable() != null ) { - value += "()"; - } - return new ValueProvider( value ); - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/XmlConstants.java b/processor/src/main/java/org/mapstruct/ap/internal/util/XmlConstants.java index 5a341d8815..532b9f0bce 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/XmlConstants.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/XmlConstants.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; @@ -25,19 +12,14 @@ */ public final class XmlConstants { - public static final String JAVAX_XML_DATATYPE_XMLGREGORIAN_CALENDAR = "javax.xml.datatype.XMLGregorianCalendar"; - private static final boolean IS_XML_GREGORIAN_CALENDAR_PRESENT = ClassUtils.isPresent( - JAVAX_XML_DATATYPE_XMLGREGORIAN_CALENDAR, - XmlConstants.class.getClassLoader() - ); + // CHECKSTYLE:OFF + public static final String JAVAX_XML_XML_GREGORIAN_CALENDAR = "javax.xml.datatype.XMLGregorianCalendar"; + public static final String JAVAX_XML_DATATYPE_CONFIGURATION_EXCEPTION = "javax.xml.datatype.DatatypeConfigurationException"; + public static final String JAVAX_XML_DATATYPE_FACTORY = "javax.xml.datatype.DatatypeFactory"; + public static final String JAVAX_XML_DATATYPE_CONSTANTS = "javax.xml.datatype.DatatypeConstants"; + // CHECKSTYLE:ON private XmlConstants() { } - /** - * @return {@code true} if the {@link javax.xml.datatype.XMLGregorianCalendar} is present, {@code false} otherwise - */ - public static boolean isXmlGregorianCalendarPresent() { - return IS_XML_GREGORIAN_CALENDAR_PRESENT; - } } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AbstractAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AbstractAccessor.java deleted file mode 100644 index fd1ad4830d..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AbstractAccessor.java +++ /dev/null @@ -1,54 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.accessor; - -import java.util.Set; - -import javax.lang.model.element.Element; -import javax.lang.model.element.Modifier; -import javax.lang.model.element.Name; - -/** - * This is an abstract implementation of an {@link Accessor} that provides the common implementation. - * - * @author Filip Hrisafov - */ -abstract class AbstractAccessor implements Accessor { - - protected final T element; - - AbstractAccessor(T element) { - this.element = element; - } - - @Override - public Name getSimpleName() { - return element.getSimpleName(); - } - - @Override - public Set getModifiers() { - return element.getModifiers(); - } - - @Override - public T getElement() { - return element; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/Accessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/Accessor.java index 4e43d3e79c..d624b7788a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/Accessor.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/Accessor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util.accessor; @@ -22,7 +9,7 @@ import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; -import javax.lang.model.element.Name; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.TypeMirror; /** @@ -36,7 +23,7 @@ public interface Accessor { * This returns the type that this accessor gives as a return. * * e.g. The {@link ExecutableElement#getReturnType()} if this is a method accessor, - * or {@link javax.lang.model.element.VariableElement#asType()} for field accessors. + * or {@link VariableElement#asType()} for field accessors. * * @return the type that the accessor gives as a return */ @@ -45,7 +32,7 @@ public interface Accessor { /** * @return the simple name of the accessor */ - Name getSimpleName(); + String getSimpleName(); /** * @return the set of modifiers that the accessor has @@ -53,12 +40,12 @@ public interface Accessor { Set getModifiers(); /** - * @return the {@link ExecutableElement}, or {@code null} if the accessor does not have one + * @return the underlying {@link Element}, {@link VariableElement} or {@link ExecutableElement} */ - ExecutableElement getExecutable(); + Element getElement(); /** - * @return the underlying {@link Element} + * @return type of the accessor */ - Element getElement(); + AccessorType getAccessorType(); } diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AccessorType.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AccessorType.java new file mode 100644 index 0000000000..112c1c512d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/AccessorType.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +public enum AccessorType { + + PARAMETER, + FIELD, + GETTER, + SETTER, + ADDER; + + public boolean isFieldAssignment() { + return this == FIELD || this == PARAMETER; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/DelegateAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/DelegateAccessor.java new file mode 100644 index 0000000000..5ebc835ba1 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/DelegateAccessor.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +import java.util.Set; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.type.TypeMirror; + +/** + * An {@link Accessor} which delegates all calls to another {@link Accessor}. + * + * @author Filip Hrisafov + */ +public abstract class DelegateAccessor implements Accessor { + + protected final Accessor delegate; + + protected DelegateAccessor(Accessor delegate) { + this.delegate = delegate; + } + + @Override + public TypeMirror getAccessedType() { + return delegate.getAccessedType(); + } + + @Override + public String getSimpleName() { + return delegate.getSimpleName(); + } + + @Override + public Set getModifiers() { + return delegate.getModifiers(); + } + + @Override + public Element getElement() { + return delegate.getElement(); + } + + @Override + public AccessorType getAccessorType() { + return delegate.getAccessorType(); + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ElementAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ElementAccessor.java new file mode 100644 index 0000000000..4b363815b7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ElementAccessor.java @@ -0,0 +1,75 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +import java.util.Set; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; + +/** + * An {@link Accessor} that wraps a {@link Element}. + * Used for getter, setter, filed, constructor, record-class, etc. + * @author Filip Hrisafov + * @author Tang Yang + */ +public class ElementAccessor implements Accessor { + + private final Element element; + private final String name; + private final AccessorType accessorType; + private final TypeMirror accessedType; + + public ElementAccessor(VariableElement variableElement, TypeMirror accessedType) { + this( variableElement, accessedType, AccessorType.FIELD ); + } + + public ElementAccessor(Element element, TypeMirror accessedType, String name) { + this.element = element; + this.name = name; + this.accessedType = accessedType; + this.accessorType = AccessorType.PARAMETER; + } + + public ElementAccessor(Element element, TypeMirror accessedType, AccessorType accessorType) { + this.element = element; + this.accessedType = accessedType; + this.accessorType = accessorType; + this.name = null; + } + + @Override + public TypeMirror getAccessedType() { + return accessedType != null ? accessedType : element.asType(); + } + + @Override + public String getSimpleName() { + return name != null ? name : element.getSimpleName().toString(); + } + + @Override + public Set getModifiers() { + return element.getModifiers(); + } + + @Override + public Element getElement() { + return element; + } + + @Override + public String toString() { + return element.toString(); + } + + @Override + public AccessorType getAccessorType() { + return accessorType; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ExecutableElementAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ExecutableElementAccessor.java deleted file mode 100644 index d4ef7f0cfe..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ExecutableElementAccessor.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.accessor; - -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.type.TypeMirror; - -/** - * An {@link Accessor} that wraps an {@link ExecutableElement}. - * - * @author Filip Hrisafov - */ -public class ExecutableElementAccessor extends AbstractAccessor { - - public ExecutableElementAccessor(ExecutableElement element) { - super( element ); - } - - @Override - public TypeMirror getAccessedType() { - return element.getReturnType(); - } - - @Override - public ExecutableElement getExecutable() { - return element; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/MapValueAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/MapValueAccessor.java new file mode 100644 index 0000000000..7a708995cd --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/MapValueAccessor.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +import java.util.Collections; +import java.util.Set; +import javax.lang.model.element.Element; +import javax.lang.model.element.Modifier; +import javax.lang.model.type.TypeMirror; + +/** + * An {@link Accessor} that wraps a Map value. + * + * @author Christian Kosmowski + */ +public class MapValueAccessor implements ReadAccessor { + + private final TypeMirror valueTypeMirror; + private final String simpleName; + private final Element element; + + public MapValueAccessor(Element element, TypeMirror valueTypeMirror, String simpleName) { + this.element = element; + this.valueTypeMirror = valueTypeMirror; + this.simpleName = simpleName; + } + + @Override + public TypeMirror getAccessedType() { + return valueTypeMirror; + } + + @Override + public String getSimpleName() { + return this.simpleName; + } + + @Override + public Set getModifiers() { + return Collections.emptySet(); + } + + @Override + public Element getElement() { + return this.element; + } + + @Override + public AccessorType getAccessorType() { + return AccessorType.GETTER; + } + + @Override + public String getReadValueSource() { + return "get( \"" + getSimpleName() + "\" )"; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/PresenceCheckAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/PresenceCheckAccessor.java new file mode 100644 index 0000000000..d96788b7f7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/PresenceCheckAccessor.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +import javax.lang.model.element.ExecutableElement; + +/** + * Accessor for presence checks. + * + * @author Filip Hrisafov + */ +public interface PresenceCheckAccessor { + + String getPresenceCheckSuffix(); + + static PresenceCheckAccessor methodInvocation(ExecutableElement element) { + return suffix( "." + element.getSimpleName() + "()" ); + } + + static PresenceCheckAccessor mapContainsKey(String propertyName) { + return suffix( ".containsKey( \"" + propertyName + "\" )" ); + } + + static PresenceCheckAccessor suffix(String suffix) { + return () -> suffix; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ReadAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ReadAccessor.java new file mode 100644 index 0000000000..4be3c26ff9 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ReadAccessor.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeMirror; + +/** + * An {@link Accessor} that can be used for reading a property from a bean. + * + * @author Filip Hrisafov + */ +public interface ReadAccessor extends Accessor { + + String getReadValueSource(); + + static ReadAccessor fromField(VariableElement variableElement, TypeMirror accessedType) { + return new ReadDelegateAccessor( new ElementAccessor( variableElement, accessedType ) ) { + @Override + public String getReadValueSource() { + return getSimpleName(); + } + }; + } + + static ReadAccessor fromRecordComponent(Element element, TypeMirror accessedType) { + return new ReadDelegateAccessor( new ElementAccessor( element, accessedType, AccessorType.GETTER ) ) { + @Override + public String getReadValueSource() { + return getSimpleName() + "()"; + } + }; + } + + static ReadAccessor fromGetter(ExecutableElement element, TypeMirror accessedType) { + return new ReadDelegateAccessor( new ElementAccessor( element, accessedType, AccessorType.GETTER ) ) { + @Override + public String getReadValueSource() { + return getSimpleName() + "()"; + } + }; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ReadDelegateAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ReadDelegateAccessor.java new file mode 100644 index 0000000000..aa93936662 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/ReadDelegateAccessor.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.accessor; + +/** + * {@link ReadAccessor} that delegates to another {@link Accessor} and requires an implementation of + * {@link #getSimpleName()} + * + * @author Filip Hrisafov + */ +public abstract class ReadDelegateAccessor extends DelegateAccessor implements ReadAccessor { + + protected ReadDelegateAccessor(Accessor delegate) { + super( delegate ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/VariableElementAccessor.java b/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/VariableElementAccessor.java deleted file mode 100644 index 6464f90793..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/accessor/VariableElementAccessor.java +++ /dev/null @@ -1,45 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.accessor; - -import javax.lang.model.element.ExecutableElement; -import javax.lang.model.element.VariableElement; -import javax.lang.model.type.TypeMirror; - -/** - * An {@link Accessor} that wraps a {@link VariableElement}. - * - * @author Filip Hrisafov - */ -public class VariableElementAccessor extends AbstractAccessor { - - public VariableElementAccessor(VariableElement element) { - super( element ); - } - - @Override - public TypeMirror getAccessedType() { - return element.asType(); - } - - @Override - public ExecutableElement getExecutable() { - return null; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/kotlin/KotlinMetadata.java b/processor/src/main/java/org/mapstruct/ap/internal/util/kotlin/KotlinMetadata.java new file mode 100644 index 0000000000..66a6fafc02 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/kotlin/KotlinMetadata.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.internal.util.kotlin; + +import java.util.List; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.type.TypeMirror; + +/** + * Information about a type in case it's a Kotlin type. + * + * @author Filip Hrisafov + */ +public interface KotlinMetadata { + + boolean isDataClass(); + + boolean isSealedClass(); + + ExecutableElement determinePrimaryConstructor(List constructors); + + List getPermittedSubclasses(); +} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/util/package-info.java index 72f81a43ec..5dbc4e0853 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/util/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/EclipseAsMemberOfWorkaround.java b/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/EclipseAsMemberOfWorkaround.java deleted file mode 100644 index 1307219b34..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/EclipseAsMemberOfWorkaround.java +++ /dev/null @@ -1,196 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.workarounds; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Types; - -import org.eclipse.jdt.core.compiler.CharOperation; -import org.eclipse.jdt.internal.compiler.apt.dispatch.BaseProcessingEnvImpl; -import org.eclipse.jdt.internal.compiler.apt.model.ElementImpl; -import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; -import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; -import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; - -/** - * Contains the workaround for {@link Types#asMemberOf(DeclaredType, Element)} using Eclipse implementation types. - *

      - * This class may only be accessed through {@link EclipseClassLoaderBridge} when running within Eclipse - * - * @author Andreas Gudian - */ -final class EclipseAsMemberOfWorkaround { - private EclipseAsMemberOfWorkaround() { - } - - /** - * Eclipse-specific implementation of {@link Types#asMemberOf(DeclaredType, Element)}. - *

      - * Returns {@code null} if the implementation could not determine the result. - */ - static TypeMirror asMemberOf(ProcessingEnvironment environment, DeclaredType containing, - Element element) { - - ElementImpl elementImpl = tryCast( element, ElementImpl.class ); - BaseProcessingEnvImpl env = tryCast( environment, BaseProcessingEnvImpl.class ); - - if ( elementImpl == null || env == null ) { - return null; - } - - ReferenceBinding referenceBinding = - (ReferenceBinding) ( (ElementImpl) environment.getTypeUtils().asElement( containing ) )._binding; - - MethodBinding methodBinding = (MethodBinding) elementImpl._binding; - - // matches in super-classes have priority - MethodBinding inSuperclassHiearchy = findInSuperclassHierarchy( methodBinding, referenceBinding ); - - if ( inSuperclassHiearchy != null ) { - return env.getFactory().newTypeMirror( inSuperclassHiearchy ); - } - - // if nothing was found, traverse the interfaces and collect all candidate methods that match - List candidatesFromInterfaces = new ArrayList(); - - collectFromInterfaces( - methodBinding, - referenceBinding, - new HashSet(), - candidatesFromInterfaces ); - - // there can be multiple matches for the same method name from adjacent interface hierarchies. - Collections.sort( candidatesFromInterfaces, MostSpecificMethodBindingComparator.INSTANCE ); - - if ( !candidatesFromInterfaces.isEmpty() ) { - // return the most specific match - return env.getFactory().newTypeMirror( candidatesFromInterfaces.get( 0 ) ); - } - - return null; - } - - private static T tryCast(Object instance, Class type) { - if ( instance != null && type.isInstance( instance ) ) { - return type.cast( instance ); - } - - return null; - } - - private static void collectFromInterfaces(MethodBinding methodBinding, ReferenceBinding typeBinding, - Set visitedTypes, List found) { - if ( typeBinding == null ) { - return; - } - - // also check the interfaces of the superclass hierarchy (the superclasses themselves don't contain a match, - // we checked that already) - collectFromInterfaces( methodBinding, typeBinding.superclass(), visitedTypes, found ); - - for ( ReferenceBinding ifc : typeBinding.superInterfaces() ) { - if ( visitedTypes.contains( ifc ) ) { - continue; - } - - visitedTypes.add( ifc ); - - // finding a match in one interface - MethodBinding f = findMatchingMethodBinding( methodBinding, ifc.methods() ); - - if ( f == null ) { - collectFromInterfaces( methodBinding, ifc, visitedTypes, found ); - } - else { - // no need for recursion if we found a candidate in this type already - found.add( f ); - } - } - } - - /** - * @param baseMethod binding to compare against - * @param methods the candidate methods - * @return The method from the list of candidates that matches the name and original/erasure of - * {@code methodBinding}, or {@code null} if none was found. - */ - private static MethodBinding findMatchingMethodBinding(MethodBinding baseMethod, MethodBinding[] methods) { - for ( MethodBinding method : methods ) { - if ( CharOperation.equals( method.selector, baseMethod.selector ) - && ( method.original() == baseMethod || method.areParameterErasuresEqual( baseMethod ) ) ) { - return method; - } - } - - return null; - } - - private static MethodBinding findInSuperclassHierarchy(MethodBinding baseMethod, ReferenceBinding typeBinding) { - while ( typeBinding != null ) { - MethodBinding matching = findMatchingMethodBinding( baseMethod, typeBinding.methods() ); - if ( matching != null ) { - return matching; - } - - typeBinding = typeBinding.superclass(); - } - - return null; - } - - /** - * Compares MethodBindings by their signature: the more specific method is considered lower. - * - * @author Andreas Gudian - */ - private static final class MostSpecificMethodBindingComparator implements Comparator { - private static final MostSpecificMethodBindingComparator INSTANCE = new MostSpecificMethodBindingComparator(); - - @Override - public int compare(MethodBinding first, MethodBinding second) { - boolean firstParamsAssignableFromSecond = - first.areParametersCompatibleWith( second.parameters ); - boolean secondParamsAssignableFromFirst = - second.areParametersCompatibleWith( first.parameters ); - - if ( firstParamsAssignableFromSecond != secondParamsAssignableFromFirst ) { - return firstParamsAssignableFromSecond ? 1 : -1; - } - - if ( TypeBinding.equalsEquals( first.returnType, second.returnType ) ) { - return 0; - } - - boolean firstReturnTypeAssignableFromSecond = - second.returnType.isCompatibleWith( first.returnType ); - - return firstReturnTypeAssignableFromSecond ? 1 : -1; - } - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/EclipseClassLoaderBridge.java b/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/EclipseClassLoaderBridge.java deleted file mode 100644 index 0deab8d99a..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/EclipseClassLoaderBridge.java +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.workarounds; - -import java.lang.reflect.Method; -import java.net.URLClassLoader; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeMirror; - -/** - * In Eclipse 4.6, the ClassLoader of the annotation processor does not provide access to the implementation types of - * the APT-API anymore, so we need to create a new ClassLoader containing the processor class path URLs and having the - * ClassLoader of the APT-API implementations as parent. The method invocation then consequently needs to be done via - * reflection. - * - * @author Andreas Gudian - */ -class EclipseClassLoaderBridge { - private static final String ECLIPSE_AS_MEMBER_OF_WORKAROUND = - "org.mapstruct.ap.internal.util.workarounds.EclipseAsMemberOfWorkaround"; - - private static ClassLoader classLoader; - private static Method asMemberOf; - - private EclipseClassLoaderBridge() { - } - - /** - * Invokes {@link EclipseAsMemberOfWorkaround#asMemberOf(ProcessingEnvironment, DeclaredType, Element)} via - * reflection using a special ClassLoader. - */ - static TypeMirror invokeAsMemberOfWorkaround(ProcessingEnvironment env, DeclaredType containing, Element element) - throws Exception { - return (TypeMirror) getAsMemberOf( element.getClass().getClassLoader() ).invoke( - null, - env, - containing, - element ); - } - - private static ClassLoader getOrCreateClassLoader(ClassLoader parent) { - if ( classLoader == null ) { - classLoader = new URLClassLoader( - ( (URLClassLoader) EclipseClassLoaderBridge.class.getClassLoader() ).getURLs(), - parent ); - } - - return classLoader; - } - - private static Method getAsMemberOf(ClassLoader platformClassLoader) throws Exception { - if ( asMemberOf == null ) { - Class workaroundClass = - getOrCreateClassLoader( platformClassLoader ).loadClass( ECLIPSE_AS_MEMBER_OF_WORKAROUND ); - - Method found = workaroundClass.getDeclaredMethod( - "asMemberOf", - ProcessingEnvironment.class, - DeclaredType.class, - Element.class ); - - found.setAccessible( true ); - - asMemberOf = found; - } - - return asMemberOf; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/SpecificCompilerWorkarounds.java b/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/SpecificCompilerWorkarounds.java deleted file mode 100644 index eb3ae9503c..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/SpecificCompilerWorkarounds.java +++ /dev/null @@ -1,153 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.workarounds; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.version.VersionInformation; - -/** - * Contains workarounds for various quirks in specific compilers. - * - * @author Sjaak Derksen - * @author Andreas Gudian - */ -public class SpecificCompilerWorkarounds { - private SpecificCompilerWorkarounds() { - } - - /** - * Tests whether one type is assignable to another, checking for VOID first. - * - * @param types the type utils - * @param t1 the first type - * @param t2 the second type - * @return {@code true} if and only if the first type is assignable to the second - * @throws IllegalArgumentException if given an executable or package type - */ - static boolean isAssignable(Types types, TypeMirror t1, TypeMirror t2) { - if ( t1.getKind() == TypeKind.VOID ) { - return false; - } - - return types.isAssignable( t1, t2 ); - } - - /** - * Tests whether one type is a subtype of another. Any type is considered to be a subtype of itself. Also see JLS section 4.10, Subtyping. - *

      - * Work-around for a bug related to sub-typing in the Eclipse JSR 269 implementation. - * - * @param types the type utils - * @param t1 the first type - * @param t2 the second type - * @return {@code true} if and only if the first type is a subtype of the second - * @throws IllegalArgumentException if given an executable or package type - */ - static boolean isSubtype(Types types, TypeMirror t1, TypeMirror t2) { - if ( t1.getKind() == TypeKind.VOID ) { - return false; - } - - return types.isSubtype( erasure( types, t1 ), erasure( types, t2 ) ); - } - - /** - * Returns the erasure of a type. - *

      - * Performs an additional test on the given type to check if it is not void. Calling - * {@link Types#erasure(TypeMirror)} with a void kind type will create a ClassCastException in Eclipse JDT. See the - * JLS, section 4.6 Type Erasure, for reference. - * - * @param types the type utils - * @param t the type to be erased - * @return the erasure of the given type - * @throws IllegalArgumentException if given a package type - */ - static TypeMirror erasure(Types types, TypeMirror t) { - if ( t.getKind() == TypeKind.VOID || t.getKind() == TypeKind.NULL ) { - return t; - } - else { - return types.erasure( t ); - } - } - - /** - * When running during Eclipse Incremental Compilation, we might get a TypeElement that has an UnresolvedTypeBinding - * and which is not automatically resolved. In that case, getEnclosedElements returns an empty list. We take that as - * a hint to check if the TypeElement resolved by FQN might have any enclosed elements and, if so, return the - * resolved element. - * - * @param elementUtils element utils - * @param element the original element - * @return the element freshly resolved using the qualified name, if the original element did not return any - * enclosed elements, whereas the resolved element does return enclosed elements. - */ - public static TypeElement replaceTypeElementIfNecessary(Elements elementUtils, TypeElement element) { - if ( element.getEnclosedElements().isEmpty() ) { - TypeElement resolvedByName = elementUtils.getTypeElement( element.getQualifiedName() ); - if ( resolvedByName != null && !resolvedByName.getEnclosedElements().isEmpty() ) { - return resolvedByName; - } - } - return element; - } - - /** - * Workaround for Bugs in the Eclipse implementation of {@link Types#asMemberOf(DeclaredType, Element)}. - * - * @see Eclipse Bug 382590 (fixed in Eclipse 4.6) - * @see Eclipse Bug 481555 - */ - static TypeMirror asMemberOf(Types typeUtils, ProcessingEnvironment env, VersionInformation versionInformation, - DeclaredType containing, Element element) { - TypeMirror result = null; - Exception lastException = null; - try { - try { - result = typeUtils.asMemberOf( containing, element ); - } - catch ( IllegalArgumentException e ) { - lastException = e; - if ( versionInformation.isEclipseJDTCompiler() ) { - result = EclipseClassLoaderBridge.invokeAsMemberOfWorkaround( env, containing, element ); - } - } - } - catch ( Exception e ) { - lastException = e; - } - - if ( null == result ) { - throw new RuntimeException( "Fallback implementation of asMemberOf didn't work for " - + element + " in " + containing, lastException ); - } - - return result; - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/TypesDecorator.java b/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/TypesDecorator.java deleted file mode 100644 index d4d0641c05..0000000000 --- a/processor/src/main/java/org/mapstruct/ap/internal/util/workarounds/TypesDecorator.java +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.util.workarounds; - -import java.util.List; - -import javax.annotation.processing.ProcessingEnvironment; -import javax.lang.model.element.Element; -import javax.lang.model.element.TypeElement; -import javax.lang.model.type.ArrayType; -import javax.lang.model.type.DeclaredType; -import javax.lang.model.type.ExecutableType; -import javax.lang.model.type.NoType; -import javax.lang.model.type.NullType; -import javax.lang.model.type.PrimitiveType; -import javax.lang.model.type.TypeKind; -import javax.lang.model.type.TypeMirror; -import javax.lang.model.type.WildcardType; -import javax.lang.model.util.Types; - -import org.mapstruct.ap.internal.version.VersionInformation; - -/** - * Replaces the usage of {@link Types} within MapStruct by delegating to the original implementation or to our specific - * workarounds if necessary. - * - * @author Andreas Gudian - */ -public class TypesDecorator implements Types { - private final Types delegate; - private final ProcessingEnvironment processingEnv; - private final VersionInformation versionInformation; - - public TypesDecorator(ProcessingEnvironment processingEnv, VersionInformation versionInformation) { - this.delegate = processingEnv.getTypeUtils(); - this.processingEnv = processingEnv; - this.versionInformation = versionInformation; - } - - @Override - public Element asElement(TypeMirror t) { - return delegate.asElement( t ); - } - - @Override - public boolean isSameType(TypeMirror t1, TypeMirror t2) { - return delegate.isSameType( t1, t2 ); - } - - @Override - public boolean isSubtype(TypeMirror t1, TypeMirror t2) { - return SpecificCompilerWorkarounds.isSubtype( delegate, t1, t2 ); - } - - @Override - public boolean isAssignable(TypeMirror t1, TypeMirror t2) { - return SpecificCompilerWorkarounds.isAssignable( delegate, t1, t2 ); - } - - @Override - public boolean contains(TypeMirror t1, TypeMirror t2) { - return delegate.contains( t1, t2 ); - } - - @Override - public boolean isSubsignature(ExecutableType m1, ExecutableType m2) { - return delegate.isSubsignature( m1, m2 ); - } - - @Override - public List directSupertypes(TypeMirror t) { - return delegate.directSupertypes( t ); - } - - @Override - public TypeMirror erasure(TypeMirror t) { - return SpecificCompilerWorkarounds.erasure( delegate, t ); - } - - @Override - public TypeElement boxedClass(PrimitiveType p) { - return delegate.boxedClass( p ); - } - - @Override - public PrimitiveType unboxedType(TypeMirror t) { - return delegate.unboxedType( t ); - } - - @Override - public TypeMirror capture(TypeMirror t) { - return delegate.capture( t ); - } - - @Override - public PrimitiveType getPrimitiveType(TypeKind kind) { - return delegate.getPrimitiveType( kind ); - } - - @Override - public NullType getNullType() { - return delegate.getNullType(); - } - - @Override - public NoType getNoType(TypeKind kind) { - return delegate.getNoType( kind ); - } - - @Override - public ArrayType getArrayType(TypeMirror componentType) { - return delegate.getArrayType( componentType ); - } - - @Override - public WildcardType getWildcardType(TypeMirror extendsBound, TypeMirror superBound) { - return delegate.getWildcardType( extendsBound, superBound ); - } - - @Override - public DeclaredType getDeclaredType(TypeElement typeElem, TypeMirror... typeArgs) { - return delegate.getDeclaredType( typeElem, typeArgs ); - } - - @Override - public DeclaredType getDeclaredType(DeclaredType containing, TypeElement typeElem, TypeMirror... typeArgs) { - return delegate.getDeclaredType( containing, typeElem, typeArgs ); - } - - @Override - public TypeMirror asMemberOf(DeclaredType containing, Element element) { - return SpecificCompilerWorkarounds.asMemberOf( - delegate, - processingEnv, - versionInformation, - containing, - element ); - } -} diff --git a/processor/src/main/java/org/mapstruct/ap/internal/version/VersionInformation.java b/processor/src/main/java/org/mapstruct/ap/internal/version/VersionInformation.java index 923158d07b..a30a383c0c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/version/VersionInformation.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/version/VersionInformation.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.version; @@ -32,6 +19,14 @@ public interface VersionInformation { String getCompiler(); + boolean isSourceVersionAtLeast9(); + + boolean isSourceVersionAtLeast11(); + + boolean isSourceVersionAtLeast14(); + + boolean isSourceVersionAtLeast19(); + boolean isEclipseJDTCompiler(); boolean isJavacCompiler(); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/version/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/version/package-info.java index 867f6cae78..114194190b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/version/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/version/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerModelElementWriter.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerModelElementWriter.java index ea8a6d29e9..d3991ce1da 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerModelElementWriter.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerModelElementWriter.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.writer; import java.io.Writer; import java.util.Map; -import org.mapstruct.ap.internal.writer.Writable.Context; - import freemarker.ext.beans.BeanModel; import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.SimpleMapModel; @@ -31,6 +16,7 @@ import freemarker.template.TemplateHashModel; import freemarker.template.TemplateModel; import freemarker.template.TemplateModelException; +import org.mapstruct.ap.internal.writer.Writable.Context; /** * Delegate for writing given {@link Writable}s into a {@link Writer} using diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerWritable.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerWritable.java index 090846476d..e8aa8fcf3a 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerWritable.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/FreeMarkerWritable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.writer; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/IndentationCorrectingWriter.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/IndentationCorrectingWriter.java index 0ff950dc1b..25cea82c8c 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/IndentationCorrectingWriter.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/IndentationCorrectingWriter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.writer; @@ -50,7 +37,7 @@ class IndentationCorrectingWriter extends Writer { * Set to true to enable output of written characters on the console. */ private static final boolean DEBUG = false; - private static final String LINE_SEPARATOR = System.getProperty( "line.separator" ); + private static final String LINE_SEPARATOR = System.lineSeparator( ); private static final boolean IS_WINDOWS = System.getProperty( "os.name" ).startsWith( "Windows" ); private State currentState = State.START_OF_LINE; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelIncludeDirective.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelIncludeDirective.java index 975f98e0e5..ea2448ca59 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelIncludeDirective.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelIncludeDirective.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.writer; @@ -22,8 +9,6 @@ import java.util.HashMap; import java.util.Map; -import org.mapstruct.ap.internal.writer.ModelWriter.DefaultModelElementWriterContext; - import freemarker.core.Environment; import freemarker.ext.beans.BeanModel; import freemarker.template.Configuration; @@ -31,6 +16,7 @@ import freemarker.template.TemplateDirectiveModel; import freemarker.template.TemplateException; import freemarker.template.TemplateModel; +import org.mapstruct.ap.internal.writer.ModelWriter.DefaultModelElementWriterContext; /** * A {@link TemplateDirectiveModel} which allows to recursively write a graph of @@ -61,15 +47,9 @@ public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, T modelElement.write( context, env.getOut() ); } } - catch ( TemplateException te ) { + catch ( TemplateException | RuntimeException | IOException te ) { throw te; } - catch ( IOException ioe ) { - throw ioe; - } - catch ( RuntimeException re ) { - throw re; - } catch ( Exception e ) { throw new RuntimeException( e ); } @@ -110,7 +90,7 @@ private DefaultModelElementWriterContext createContext(Map params) { Map ext = new HashMap( params ); ext.remove( "object" ); - Map, Object> values = new HashMap, Object>(); + Map, Object> values = new HashMap<>(); values.put( Configuration.class, configuration ); values.put( Map.class, ext ); diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelWriter.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelWriter.java index fe9abe28c0..aeb2593e86 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelWriter.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/ModelWriter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.writer; @@ -25,19 +12,17 @@ import java.io.Reader; import java.net.URL; import java.net.URLConnection; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; - import javax.tools.FileObject; -import org.mapstruct.ap.internal.writer.Writable.Context; - import freemarker.cache.StrongCacheStorage; import freemarker.cache.TemplateLoader; import freemarker.log.Logger; import freemarker.template.Configuration; import freemarker.template.DefaultObjectWrapper; +import org.mapstruct.ap.internal.writer.Writable.Context; /** * Writes Java source files based on given mapper models, using a FreeMarker @@ -75,16 +60,13 @@ public class ModelWriter { } public void writeModel(FileObject sourceFile, Writable model) { - try { - BufferedWriter writer = new BufferedWriter( new IndentationCorrectingWriter( sourceFile.openWriter() ) ); - - Map, Object> values = new HashMap, Object>(); - values.put( Configuration.class, CONFIGURATION ); + try ( BufferedWriter writer = new BufferedWriter( new IndentationCorrectingWriter( sourceFile.openWriter() ))) { + Map, Object> values = new HashMap<>(); + values.put( Configuration.class, CONFIGURATION ); - model.write( new DefaultModelElementWriterContext( values ), writer ); + model.write( new DefaultModelElementWriterContext( values ), writer ); - writer.flush(); - writer.close(); + writer.flush(); } catch ( RuntimeException e ) { throw e; @@ -113,7 +95,7 @@ public Reader getReader(Object name, String encoding) throws IOException { InputStream is = connection.getInputStream(); - return new InputStreamReader( is, Charset.forName( "UTF-8" ) ); + return new InputStreamReader( is, StandardCharsets.UTF_8 ); } @Override @@ -141,7 +123,7 @@ static class DefaultModelElementWriterContext implements Context { private final Map, Object> values; DefaultModelElementWriterContext(Map, Object> values) { - this.values = new HashMap, Object>( values ); + this.values = new HashMap<>( values ); } @Override diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/Writable.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/Writable.java index 2ef3539f06..42724b43c9 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/Writable.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/Writable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.writer; diff --git a/processor/src/main/java/org/mapstruct/ap/internal/writer/package-info.java b/processor/src/main/java/org/mapstruct/ap/internal/writer/package-info.java index dc8cfcae46..36b72bc30b 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/writer/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/writer/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/package-info.java b/processor/src/main/java/org/mapstruct/ap/package-info.java index a2a8c67a8c..037310099c 100644 --- a/processor/src/main/java/org/mapstruct/ap/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/spi/AccessorNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/AccessorNamingStrategy.java index 9e6ed49d39..b4dde64324 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/AccessorNamingStrategy.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/AccessorNamingStrategy.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; @@ -28,6 +15,17 @@ */ public interface AccessorNamingStrategy { + /** + * Initializes the accessor naming strategy with the MapStruct processing environment. + * + * @param processingEnvironment environment for facilities + * + * @since 1.3 + */ + default void init(MapStructProcessingEnvironment processingEnvironment) { + + } + /** * Returns the type of the given method. * @@ -70,7 +68,7 @@ public interface AccessorNamingStrategy { * * @return getter name for collection properties * - * @deprecated MapStuct will not call this method anymore. Use {@link #getMethodType(ExecutableElement)} to + * @deprecated MapStruct will not call this method anymore. Use {@link #getMethodType(ExecutableElement)} to * determine the {@link MethodType}. When collections somehow need to be treated special, it should be done in * {@link #getMethodType(ExecutableElement) } as well. In the future, this method will be removed. */ diff --git a/processor/src/main/java/org/mapstruct/ap/spi/AdditionalSupportedOptionsProvider.java b/processor/src/main/java/org/mapstruct/ap/spi/AdditionalSupportedOptionsProvider.java new file mode 100644 index 0000000000..3638f70320 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/AdditionalSupportedOptionsProvider.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import java.util.Set; + +/** + * Provider for any additional supported options required for custom SPI implementations. + * The resolved values are retrieved from {@link MapStructProcessingEnvironment#getOptions()}. + */ +public interface AdditionalSupportedOptionsProvider { + + /** + * Returns the supported options required for custom SPI implementations. + * + * @return the additional supported options. + */ + Set getAdditionalSupportedOptions(); + +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.java b/processor/src/main/java/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.java index aa263ab12d..6b9e079523 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/AstModifyingAnnotationProcessor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; @@ -28,7 +15,7 @@ *

      * This contract will be queried by MapStruct when examining types referenced by mappers to be generated, most notably * the source and target types of mapping methods. If at least one AST-modifying processor announces further changes to - * such type, the generation of the affected mapper(s) will be deferred to a future round in the annnotation processing + * such type, the generation of the affected mapper(s) will be deferred to a future round in the annotation processing * cycle. *

      * Implementations are discovered via the service loader, i.e. a JAR providing an AST-modifying processor needs to diff --git a/processor/src/main/java/org/mapstruct/ap/spi/BuilderInfo.java b/processor/src/main/java/org/mapstruct/ap/spi/BuilderInfo.java index 2be9c01fb0..5e37987f75 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/BuilderInfo.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/BuilderInfo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; @@ -25,6 +12,8 @@ * Holder for the builder information. * * @author Filip Hrisafov + * + * @since 1.3 */ public class BuilderInfo { @@ -65,6 +54,10 @@ public static class Builder { private Collection buildMethods; /** + * @param method The creation method for the builder + * + * @return the builder for chaining + * * @see BuilderInfo#getBuilderCreationMethod() */ public Builder builderCreationMethod(ExecutableElement method) { @@ -73,6 +66,10 @@ public Builder builderCreationMethod(ExecutableElement method) { } /** + * @param methods the build methods for the type + * + * @return the builder for chaining + * * @see BuilderInfo#getBuildMethods() */ public Builder buildMethod(Collection methods) { @@ -82,6 +79,9 @@ public Builder buildMethod(Collection methods) { /** * Create the {@link BuilderInfo}. + * + * @return the created {@link BuilderInfo} + * * @throws IllegalArgumentException if the builder creation or build methods are {@code null} */ public BuilderInfo build() { diff --git a/processor/src/main/java/org/mapstruct/ap/spi/BuilderProvider.java b/processor/src/main/java/org/mapstruct/ap/spi/BuilderProvider.java index fb48fcce6b..419c85a39d 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/BuilderProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/BuilderProvider.java @@ -1,41 +1,34 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; /** * A service provider interface that is used to detect types that require a builder for mapping. This interface could * support automatic detection of builders for projects like Lombok, Immutables, AutoValue, etc. * @author Filip Hrisafov + * + * @since 1.3 */ public interface BuilderProvider { + /** + * Initializes the builder provider with the MapStruct processing environment. + * + * @param processingEnvironment environment for facilities + */ + default void init(MapStructProcessingEnvironment processingEnvironment) { + + } + /** * Find the builder information, if any, for the {@code type}. * * @param type the type for which a builder should be found - * @param elements the util elements that can be used for operations on program elements - * @param types the util types that can be used for operations on {@link TypeMirror}(s) - * * @return the builder info for the {@code type} if it exists, or {@code null} if there is no builder * * @throws TypeHierarchyErroneousException if the type that needs to be visited is not ready yet, this signals the @@ -43,5 +36,5 @@ public interface BuilderProvider { * @throws MoreThanOneBuilderCreationMethodException if {@code type} has more than one method that can create the * builder */ - BuilderInfo findBuilderInfo(TypeMirror type, Elements elements, Types types); + BuilderInfo findBuilderInfo(TypeMirror type); } diff --git a/processor/src/main/java/org/mapstruct/ap/spi/CaseEnumTransformationStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/CaseEnumTransformationStrategy.java new file mode 100644 index 0000000000..3a4ba18ade --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/CaseEnumTransformationStrategy.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import java.util.Arrays; +import java.util.Locale; +import java.util.stream.Collectors; + +/** + * Applies case transformation to the source enum + * + * @author jpbassinello + * @since 1.5 + */ +public class CaseEnumTransformationStrategy implements EnumTransformationStrategy { + + private static final String UPPER = "upper"; + private static final String LOWER = "lower"; + private static final String CAPITAL = "capital"; + private static final String CASE_ENUM_TRANSFORMATION_STRATEGIES = UPPER + ", " + LOWER + ", " + CAPITAL; + + @Override + public String getStrategyName() { + return "case"; + } + + @Override + public String transform(String value, String configuration) { + switch ( configuration.toLowerCase() ) { + case UPPER: + return value.toUpperCase( Locale.ROOT ); + case LOWER: + return value.toLowerCase( Locale.ROOT ); + case CAPITAL: + return capitalize( value ); + default: + throw new IllegalArgumentException( + "Unexpected configuration for enum case transformation: " + configuration + + ". Allowed values: " + CASE_ENUM_TRANSFORMATION_STRATEGIES); + } + } + + private static String capitalize(String value) { + return Arrays.stream( value.split( "_" ) ) + .map( CaseEnumTransformationStrategy::upperCaseFirst ) + .collect( Collectors.joining( "_" ) ); + } + + private static String upperCaseFirst(String value) { + char[] array = value.toCharArray(); + array[0] = Character.toUpperCase( array[0] ); + for ( int i = 1; i < array.length; i++ ) { + array[i] = Character.toLowerCase( array[i] ); + } + return new String( array ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java index a5ee1a2755..20cb1c76c1 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/DefaultAccessorNamingStrategy.java @@ -1,34 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; -import java.beans.Introspector; import java.util.regex.Pattern; - +import javax.lang.model.element.Element; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.SimpleElementVisitor6; -import javax.lang.model.util.SimpleTypeVisitor6; +import javax.lang.model.util.Elements; +import javax.lang.model.util.SimpleElementVisitor8; +import javax.lang.model.util.SimpleTypeVisitor8; +import javax.lang.model.util.Types; +import kotlin.Metadata; +import kotlin.metadata.Attributes; +import kotlin.metadata.jvm.KotlinClassMetadata; +import org.mapstruct.ap.spi.util.IntrospectorUtils; /** * The default JavaBeans-compliant implementation of the {@link AccessorNamingStrategy} service provider interface. @@ -39,6 +31,33 @@ public class DefaultAccessorNamingStrategy implements AccessorNamingStrategy { private static final Pattern JAVA_JAVAX_PACKAGE = Pattern.compile( "^javax?\\..*" ); + private static final boolean KOTLIN_METADATA_JVM_PRESENT; + + static { + boolean kotlinMetadataJvmPresent; + try { + Class.forName( + "kotlin.metadata.jvm.KotlinClassMetadata", + false, + AccessorNamingStrategy.class.getClassLoader() + ); + kotlinMetadataJvmPresent = true; + } + catch ( ClassNotFoundException e ) { + kotlinMetadataJvmPresent = false; + } + KOTLIN_METADATA_JVM_PRESENT = kotlinMetadataJvmPresent; + } + + protected Elements elementUtils; + protected Types typeUtils; + + @Override + public void init(MapStructProcessingEnvironment processingEnvironment) { + this.elementUtils = processingEnvironment.getElementUtils(); + this.typeUtils = processingEnvironment.getTypeUtils(); + } + @Override public MethodType getMethodType(ExecutableElement method) { if ( isGetterMethod( method ) ) { @@ -59,7 +78,8 @@ else if ( isPresenceCheckMethod( method ) ) { } /** - * Returns {@code true} when the {@link ExecutableElement} is a getter method. A method is a getter when it starts + * Returns {@code true} when the {@link ExecutableElement} is a getter method. A method is a getter when it + * has no parameters, starts * with 'get' and the return type is any type other than {@code void}, OR the getter starts with 'is' and the type * returned is a primitive or the wrapper for {@code boolean}. NOTE: the latter does strictly not comply to the bean * convention. The remainder of the name is supposed to reflect the property name. @@ -71,6 +91,10 @@ else if ( isPresenceCheckMethod( method ) ) { * @return {@code true} when the method is a getter. */ public boolean isGetterMethod(ExecutableElement method) { + if ( !method.getParameters().isEmpty() ) { + // If the method has parameters it can't be a getter + return false; + } String methodName = method.getSimpleName().toString(); boolean isNonBooleanGetterName = methodName.startsWith( "get" ) && methodName.length() > 3 && @@ -83,7 +107,6 @@ public boolean isGetterMethod(ExecutableElement method) { return isNonBooleanGetterName || ( isBooleanGetterName && returnTypeIsBoolean ); } - /** * Returns {@code true} when the {@link ExecutableElement} is a setter method. A setter starts with 'set'. The * remainder of the name is supposed to reflect the property name. @@ -96,15 +119,52 @@ public boolean isGetterMethod(ExecutableElement method) { public boolean isSetterMethod(ExecutableElement method) { String methodName = method.getSimpleName().toString(); - return methodName.startsWith( "set" ) && methodName.length() > 3 || isBuilderSetter( method ); + return methodName.startsWith( "set" ) && methodName.length() > 3 || isFluentSetter( method ); + } + + protected boolean isFluentSetter(ExecutableElement method) { + if ( method.getParameters().size() != 1 ) { + return false; + } + Element methodOwnerElement = method.getEnclosingElement(); + if ( !canMethodOwnerBeUsedInFluentSetter( methodOwnerElement ) ) { + return false; + } + return !isAdderWithUpperCase4thCharacter( method ) && + typeUtils.isAssignable( method.getReturnType(), methodOwnerElement.asType() ); } - protected boolean isBuilderSetter(ExecutableElement method) { - return method.getParameters().size() == 1 && - !JAVA_JAVAX_PACKAGE.matcher( method.getEnclosingElement().asType().toString() ).matches() && - !isAdderWithUpperCase4thCharacter( method ) && - //TODO The Types need to be compared with Types#isSameType(TypeMirror, TypeMirror) - method.getReturnType().toString().equals( method.getEnclosingElement().asType().toString() ); + private boolean canMethodOwnerBeUsedInFluentSetter(Element methodOwnerElement) { + if ( !( methodOwnerElement instanceof TypeElement ) ) { + return false; + } + + TypeElement typeElement = (TypeElement) methodOwnerElement; + if ( JAVA_JAVAX_PACKAGE.matcher( typeElement.getQualifiedName().toString() ).matches() ) { + return false; + } + if ( isKotlinDataClass( typeElement ) ) { + return false; + } + + return true; + } + + private boolean isKotlinDataClass(TypeElement typeElement) { + if ( !KOTLIN_METADATA_JVM_PRESENT ) { + return false; + } + + Metadata kotlinMetadata = typeElement.getAnnotation( Metadata.class ); + if ( kotlinMetadata == null ) { + return false; + } + KotlinClassMetadata classMetadata = KotlinClassMetadata.readLenient( kotlinMetadata ); + if ( classMetadata instanceof KotlinClassMetadata.Class ) { + return Attributes.isData( ( (KotlinClassMetadata.Class) classMetadata ).getKmClass() ); + } + + return false; } /** @@ -127,7 +187,6 @@ private boolean isAdderWithUpperCase4thCharacter(ExecutableElement method) { * {@link #getElementName(ExecutableElement) }. *

      * The calling MapStruct code guarantees there's only one argument. - *

      * * @param method to be analyzed * @@ -169,13 +228,24 @@ public boolean isPresenceCheckMethod(ExecutableElement method) { @Override public String getPropertyName(ExecutableElement getterOrSetterMethod) { String methodName = getterOrSetterMethod.getSimpleName().toString(); - if ( methodName.startsWith( "is" ) || methodName.startsWith( "get" ) || methodName.startsWith( "set" ) ) { - return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) ); + if ( isFluentSetter( getterOrSetterMethod ) ) { + // If this is a fluent setter that starts with set and the 4th character is an uppercase one + // then we treat it as a Java Bean style method (we get the property starting from the 4th character). + // Otherwise we treat it as a fluent setter + // For example, for the following methods: + // * public Builder setSettlementDate(String settlementDate) + // * public Builder settlementDate(String settlementDate) + // We are going to extract the same property name settlementDate + if ( methodName.startsWith( "set" ) + && methodName.length() > 3 + && Character.isUpperCase( methodName.charAt( 3 ) ) ) { + return IntrospectorUtils.decapitalize( methodName.substring( 3 ) ); + } + else { + return methodName; + } } - else if ( isBuilderSetter( getterOrSetterMethod ) ) { - return methodName; - } - return Introspector.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) ); + return IntrospectorUtils.decapitalize( methodName.substring( methodName.startsWith( "is" ) ? 2 : 3 ) ); } /** @@ -190,10 +260,10 @@ else if ( isBuilderSetter( getterOrSetterMethod ) ) { @Override public String getElementName(ExecutableElement adderMethod) { String methodName = adderMethod.getSimpleName().toString(); - return Introspector.decapitalize( methodName.substring( 3 ) ); + return IntrospectorUtils.decapitalize( methodName.substring( 3 ) ); } - /** + /** * Helper method, to obtain the fully qualified name of a type. * * @param type input type @@ -202,7 +272,7 @@ public String getElementName(ExecutableElement adderMethod) { */ protected static String getQualifiedName(TypeMirror type) { DeclaredType declaredType = type.accept( - new SimpleTypeVisitor6() { + new SimpleTypeVisitor8() { @Override public DeclaredType visitDeclared(DeclaredType t, Void p) { return t; @@ -216,7 +286,7 @@ public DeclaredType visitDeclared(DeclaredType t, Void p) { } TypeElement typeElement = declaredType.asElement().accept( - new SimpleElementVisitor6() { + new SimpleElementVisitor8() { @Override public TypeElement visitType(TypeElement e, Void p) { return e; diff --git a/processor/src/main/java/org/mapstruct/ap/spi/DefaultBuilderProvider.java b/processor/src/main/java/org/mapstruct/ap/spi/DefaultBuilderProvider.java index 365efa02f5..c1126fa9fb 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/DefaultBuilderProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/DefaultBuilderProvider.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; @@ -23,16 +10,19 @@ import java.util.Collections; import java.util.List; import java.util.regex.Pattern; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Elements; -import javax.lang.model.util.SimpleElementVisitor6; -import javax.lang.model.util.SimpleTypeVisitor6; +import javax.lang.model.util.SimpleElementVisitor8; +import javax.lang.model.util.SimpleTypeVisitor8; import javax.lang.model.util.Types; /** @@ -90,14 +80,23 @@ public class DefaultBuilderProvider implements BuilderProvider { private static final Pattern JAVA_JAVAX_PACKAGE = Pattern.compile( "^javax?\\..*" ); + protected Elements elementUtils; + protected Types typeUtils; + + @Override + public void init(MapStructProcessingEnvironment processingEnvironment) { + this.elementUtils = processingEnvironment.getElementUtils(); + this.typeUtils = processingEnvironment.getTypeUtils(); + } + @Override - public BuilderInfo findBuilderInfo(TypeMirror type, Elements elements, Types types) { + public BuilderInfo findBuilderInfo(TypeMirror type) { TypeElement typeElement = getTypeElement( type ); if ( typeElement == null ) { return null; } - return findBuilderInfo( typeElement, elements, types ); + return findBuilderInfo( typeElement ); } /** @@ -111,25 +110,23 @@ public BuilderInfo findBuilderInfo(TypeMirror type, Elements elements, Types typ * @throws TypeHierarchyErroneousException if the {@link TypeMirror} is of kind {@link TypeKind#ERROR} */ protected TypeElement getTypeElement(TypeMirror type) { - if ( type.getKind() == TypeKind.ERROR ) { - throw new TypeHierarchyErroneousException( type ); - } - DeclaredType declaredType = type.accept( - new SimpleTypeVisitor6() { - @Override - public DeclaredType visitDeclared(DeclaredType t, Void p) { - return t; - } - }, - null - ); + DeclaredType declaredType = getDeclaredType( type ); + return getTypeElement( declaredType ); + } + /** + * Find the {@link TypeElement} for the given {@link DeclaredType}. + * + * @param declaredType for which the {@link TypeElement} needs to be found. + * @return the type element or {@code null} if the declared type element is not {@link TypeElement} + */ + private TypeElement getTypeElement(DeclaredType declaredType) { if ( declaredType == null ) { return null; } return declaredType.asElement().accept( - new SimpleElementVisitor6() { + new SimpleElementVisitor8() { @Override public TypeElement visitType(TypeElement e, Void p) { return e; @@ -139,12 +136,34 @@ public TypeElement visitType(TypeElement e, Void p) { ); } + /** + * Find the {@link DeclaredType} for the given {@link TypeMirror}. + * + * @param type for which the {@link DeclaredType} needs to be found. + * @return the declared or {@code null} if the {@link TypeMirror} is not a {@link DeclaredType} + * @throws TypeHierarchyErroneousException if the {@link TypeMirror} is of kind {@link TypeKind#ERROR} + */ + private DeclaredType getDeclaredType(TypeMirror type) { + if ( type.getKind() == TypeKind.ERROR ) { + throw new TypeHierarchyErroneousException( type ); + } + return type.accept( + new SimpleTypeVisitor8() { + @Override + public DeclaredType visitDeclared(DeclaredType t, Void p) { + return t; + } + }, + null + ); + } + /** * Find the {@link BuilderInfo} for the given {@code typeElement}. *

      * The default implementation iterates over all the methods in {@code typeElement} and uses - * {@link DefaultBuilderProvider#isPossibleBuilderCreationMethod(ExecutableElement, TypeElement, Types)} and - * {@link DefaultBuilderProvider#findBuildMethods(TypeElement, TypeElement, Types)} to create the + * {@link DefaultBuilderProvider#isPossibleBuilderCreationMethod(ExecutableElement, TypeElement)} and + * {@link DefaultBuilderProvider#findBuildMethods(TypeElement, TypeElement)} to create the * {@link BuilderInfo}. *

      * The default implementation uses {@link DefaultBuilderProvider#shouldIgnore(TypeElement)} to check if the @@ -154,42 +173,110 @@ public TypeElement visitType(TypeElement e, Void p) { * thrown. * * @param typeElement the type element for which a builder searched - * @param elements the util elements that can be used for operating on the type element - * @param types the util types that can be used for operation on {@link TypeMirror}(s) - * * @return the {@link BuilderInfo} or {@code null} if no builder was found for the type - * {@link DefaultBuilderProvider#findBuildMethods(TypeElement, TypeElement, Types)} + * {@link DefaultBuilderProvider#findBuildMethods(TypeElement, TypeElement)} * @throws MoreThanOneBuilderCreationMethodException if there are multiple builder creation methods */ - protected BuilderInfo findBuilderInfo(TypeElement typeElement, Elements elements, Types types) { + protected BuilderInfo findBuilderInfo(TypeElement typeElement) { + return findBuilderInfo( typeElement, true ); + } + + protected BuilderInfo findBuilderInfo(TypeElement typeElement, boolean checkParent) { if ( shouldIgnore( typeElement ) ) { return null; } - List methods = ElementFilter.methodsIn( typeElement.getEnclosedElements() ); - List builderInfo = new ArrayList(); - for ( ExecutableElement method : methods ) { - if ( isPossibleBuilderCreationMethod( method, typeElement, types ) ) { - TypeElement builderElement = getTypeElement( method.getReturnType() ); - Collection buildMethods = findBuildMethods( builderElement, typeElement, types ); - if ( !buildMethods.isEmpty() ) { - builderInfo.add( new BuilderInfo.Builder() - .builderCreationMethod( method ) - .buildMethod( buildMethods ) - .build() - ); + // Builder infos which are determined by a static method on the type itself + List methodBuilderInfos = new ArrayList<>(); + // Builder infos which are determined by an inner builder class in the type itself + List innerClassBuilderInfos = new ArrayList<>(); + + for ( Element enclosedElement : typeElement.getEnclosedElements() ) { + if ( ElementKind.METHOD == enclosedElement.getKind() ) { + ExecutableElement method = (ExecutableElement) enclosedElement; + BuilderInfo builderInfo = determineMethodBuilderInfo( method, typeElement ); + if ( builderInfo != null ) { + methodBuilderInfos.add( builderInfo ); + } + } + else if ( ElementKind.CLASS == enclosedElement.getKind() ) { + if ( !methodBuilderInfos.isEmpty() ) { + // Small optimization to not check the inner classes + // if we already have at least one builder through a method + continue; + } + TypeElement classElement = (TypeElement) enclosedElement; + BuilderInfo builderInfo = determineInnerClassBuilderInfo( classElement, typeElement ); + if ( builderInfo != null ) { + innerClassBuilderInfos.add( builderInfo ); } } + + } + + if ( methodBuilderInfos.size() == 1 ) { + return methodBuilderInfos.get( 0 ); + } + else if ( methodBuilderInfos.size() > 1 ) { + throw new MoreThanOneBuilderCreationMethodException( typeElement.asType(), methodBuilderInfos ); } + else if ( innerClassBuilderInfos.size() == 1 ) { + return innerClassBuilderInfos.get( 0 ); + } + else if ( innerClassBuilderInfos.size() > 1 ) { + throw new MoreThanOneBuilderCreationMethodException( typeElement.asType(), innerClassBuilderInfos ); + } + + if ( checkParent ) { + return findBuilderInfo( typeElement.getSuperclass() ); + } + + return null; + } - if ( builderInfo.size() == 1 ) { - return builderInfo.get( 0 ); + private BuilderInfo determineMethodBuilderInfo(ExecutableElement method, + TypeElement typeElement) { + if ( isPossibleBuilderCreationMethod( method, typeElement ) ) { + TypeElement builderElement = getTypeElement( method.getReturnType() ); + Collection buildMethods = findBuildMethods( builderElement, typeElement ); + if ( !buildMethods.isEmpty() ) { + return new BuilderInfo.Builder() + .builderCreationMethod( method ) + .buildMethod( buildMethods ) + .build(); + } } - else if ( builderInfo.size() > 1 ) { - throw new MoreThanOneBuilderCreationMethodException( typeElement.asType(), builderInfo ); + + return null; + } + + private BuilderInfo determineInnerClassBuilderInfo(TypeElement innerClassElement, + TypeElement typeElement) { + if ( innerClassElement.getModifiers().contains( Modifier.PUBLIC ) + && innerClassElement.getModifiers().contains( Modifier.STATIC ) + && innerClassElement.getSimpleName().toString().endsWith( "Builder" ) ) { + for ( Element element : innerClassElement.getEnclosedElements() ) { + if ( ElementKind.CONSTRUCTOR == element.getKind() ) { + ExecutableElement constructor = (ExecutableElement) element; + if ( constructor.getParameters().isEmpty() ) { + // We have a no-arg constructor + // Now check if we have build methods + Collection buildMethods = findBuildMethods( innerClassElement, typeElement ); + if ( !buildMethods.isEmpty() ) { + return new BuilderInfo.Builder() + .builderCreationMethod( constructor ) + .buildMethod( buildMethods ) + .build(); + } + // If we don't have any build methods + // then we can stop since we are only interested in the no-arg constructor + return null; + } + } + } } - return findBuilderInfo( typeElement.getSuperclass(), elements, types ); + return null; } /** @@ -205,64 +292,110 @@ else if ( builderInfo.size() > 1 ) { * * @param method The method that needs to be checked * @param typeElement the enclosing element of the method, i.e. the type in which the method is located in - * @param types the util types that can be used for operations on {@link TypeMirror}(s) - * * @return {@code true} if the {@code method} is a possible builder creation method, {@code false} otherwise */ - protected boolean isPossibleBuilderCreationMethod(ExecutableElement method, TypeElement typeElement, Types types) { + protected boolean isPossibleBuilderCreationMethod(ExecutableElement method, TypeElement typeElement) { return method.getParameters().isEmpty() && method.getModifiers().contains( Modifier.PUBLIC ) && method.getModifiers().contains( Modifier.STATIC ) - && !types.isSameType( method.getReturnType(), typeElement.asType() ); + && method.getReturnType().getKind() != TypeKind.VOID + // Only compare raw elements + // Reason: if the method is a generic method ( Holder build()) and the type element is (Holder) + // then the return type of the method does not match the type of the type element + && !typeUtils.isSameType( + typeUtils.erasure( method.getReturnType() ), + typeUtils.erasure( typeElement.asType() ) + ); } /** * Searches for a build method for {@code typeElement} within the {@code builderElement}. *

      * The default implementation iterates over each method in {@code builderElement} and uses - * {@link DefaultBuilderProvider#isBuildMethod(ExecutableElement, TypeElement, Types)} to check if the method is a - * build method for {@code typeElement}. + * {@link DefaultBuilderProvider#isBuildMethod(ExecutableElement, DeclaredType, TypeElement)} + * to check if the method is a build method for {@code typeElement}. *

      * The default implementation uses {@link DefaultBuilderProvider#shouldIgnore(TypeElement)} to check if the * {@code builderElement} should be ignored, i.e. not checked for build elements. - *

      - * If there are multiple methods that satisfy - * {@link DefaultBuilderProvider#isBuildMethod(ExecutableElement, TypeElement, Types)} and one of those methods - * is names {@code build} that that method would be considered as a build method. + * * @param builderElement the element for the builder * @param typeElement the element for the type that is being built - * @param types the util types tat can be used for operations on {@link TypeMirror}(s) - * * @return the build method for the {@code typeElement} if it exists, or {@code null} if it does not * {@code build} */ - protected Collection findBuildMethods(TypeElement builderElement, TypeElement typeElement, - Types types) { + protected Collection findBuildMethods(TypeElement builderElement, TypeElement typeElement) { + if ( shouldIgnore( builderElement ) || typeElement == null ) { + return Collections.emptyList(); + } + DeclaredType builderType = getDeclaredType( builderElement.asType() ); + + if ( builderType == null ) { + return Collections.emptyList(); + } + + return findBuildMethods( builderElement, builderType, typeElement ); + } + + private Collection findBuildMethods(TypeElement builderElement, DeclaredType builderType, + TypeElement typeElement) { if ( shouldIgnore( builderElement ) ) { return Collections.emptyList(); } List builderMethods = ElementFilter.methodsIn( builderElement.getEnclosedElements() ); - List buildMethods = new ArrayList(); + List buildMethods = new ArrayList<>(); for ( ExecutableElement buildMethod : builderMethods ) { - if ( isBuildMethod( buildMethod, typeElement, types ) ) { + if ( isBuildMethod( buildMethod, builderType, typeElement ) ) { buildMethods.add( buildMethod ); } } - if ( buildMethods.isEmpty() ) { - return findBuildMethods( - getTypeElement( builderElement.getSuperclass() ), - typeElement, - types - ); + if ( !buildMethods.isEmpty() ) { + return buildMethods; + } + + Collection parentClassBuildMethods = findBuildMethods( + getTypeElement( builderElement.getSuperclass() ), + builderType, + typeElement + ); + + if ( !parentClassBuildMethods.isEmpty() ) { + return parentClassBuildMethods; + } + + List interfaces = builderElement.getInterfaces(); + if ( interfaces.isEmpty() ) { + return Collections.emptyList(); + } + + Collection interfaceBuildMethods = new ArrayList<>(); + + for ( TypeMirror builderInterface : interfaces ) { + interfaceBuildMethods.addAll( findBuildMethods( + getTypeElement( builderInterface ), + builderType, + typeElement + ) ); } - return buildMethods; + return interfaceBuildMethods; + } + + /** + * @see #isBuildMethod(ExecutableElement, DeclaredType, TypeElement) + * @deprecated use {@link #isBuildMethod(ExecutableElement, DeclaredType, TypeElement)} instead + */ + @Deprecated + protected boolean isBuildMethod(ExecutableElement buildMethod, TypeElement typeElement) { + return buildMethod.getParameters().isEmpty() && + buildMethod.getModifiers().contains( Modifier.PUBLIC ) + && typeUtils.isAssignable( buildMethod.getReturnType(), typeElement.asType() ); } /** - * Checks if the {@code buildMethod} is a method that creates {@code typeElement}. + * Checks if the {@code buildMethod} is a method that creates the {@code typeElement} + * as a member of the {@code builderType}. *

      * The default implementation considers a method to be a build method if the following is satisfied: *

        @@ -272,16 +405,23 @@ protected Collection findBuildMethods(TypeElement builderElem *
      * * @param buildMethod the method that should be checked + * @param builderType the type of the builder in which the {@code buildMethod} is located in * @param typeElement the type element that needs to be built - * @param types the util types that can be used for operations on {@link TypeMirror}(s) - * * @return {@code true} if the {@code buildMethod} is a build method for {@code typeElement}, {@code false} * otherwise */ - protected boolean isBuildMethod(ExecutableElement buildMethod, TypeElement typeElement, Types types) { - return buildMethod.getParameters().isEmpty() && - buildMethod.getModifiers().contains( Modifier.PUBLIC ) - && types.isAssignable( buildMethod.getReturnType(), typeElement.asType() ); + protected boolean isBuildMethod(ExecutableElement buildMethod, DeclaredType builderType, TypeElement typeElement) { + if ( !buildMethod.getParameters().isEmpty() ) { + return false; + } + if ( !buildMethod.getModifiers().contains( Modifier.PUBLIC ) ) { + return false; + } + TypeMirror buildMethodType = typeUtils.asMemberOf( builderType, buildMethod ); + if ( buildMethodType instanceof ExecutableType ) { + return typeUtils.isAssignable( ( (ExecutableType) buildMethodType ).getReturnType(), typeElement.asType() ); + } + return false; } /** @@ -295,4 +435,5 @@ protected boolean isBuildMethod(ExecutableElement buildMethod, TypeElement typeE protected boolean shouldIgnore(TypeElement typeElement) { return typeElement == null || JAVA_JAVAX_PACKAGE.matcher( typeElement.getQualifiedName() ).matches(); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumMappingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumMappingStrategy.java new file mode 100644 index 0000000000..11e1257be1 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/DefaultEnumMappingStrategy.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +/** + * The default implementation of the {@link EnumMappingStrategy} service provider interface. + * + * @author Filip Hrisafov + * + * @since 1.4 + */ +public class DefaultEnumMappingStrategy implements EnumMappingStrategy { + + protected Elements elementUtils; + protected Types typeUtils; + + @Override + public void init(MapStructProcessingEnvironment processingEnvironment) { + this.elementUtils = processingEnvironment.getElementUtils(); + this.typeUtils = processingEnvironment.getTypeUtils(); + } + + @Override + public String getDefaultNullEnumConstant(TypeElement enumType) { + return null; + } + + @Override + public String getEnumConstant(TypeElement enumType, String enumConstant) { + return enumConstant; + } + + @Override + public TypeElement getUnexpectedValueMappingExceptionType() { + return elementUtils.getTypeElement( getUnexpectedValueMappingExceptionClass().getCanonicalName() ); + } + + protected Class getUnexpectedValueMappingExceptionClass() { + return IllegalArgumentException.class; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/EnumMappingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/EnumMappingStrategy.java new file mode 100644 index 0000000000..8ad6737c63 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/EnumMappingStrategy.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import javax.lang.model.element.TypeElement; + +import org.mapstruct.util.Experimental; + +/** + * A service provider interface for the mapping between different enum constants + * + * @author Arne Seime + * @author Filip Hrisafov + * + * @since 1.4 + */ +@Experimental("This SPI can have its signature changed in subsequent releases") +public interface EnumMappingStrategy { + + /** + * Initializes the enum value mapping strategy + * + * @param processingEnvironment environment for facilities + */ + default void init(MapStructProcessingEnvironment processingEnvironment) { + + } + + /** + * Return the default enum constant to use if the source is null. + * + * @param enumType the enum + * @return enum value or null if there is no designated enum constant + */ + String getDefaultNullEnumConstant(TypeElement enumType); + + /** + * Map the enum constant to the value use for matching. + * In case you want this enum constant to match to null return {@link org.mapstruct.MappingConstants#NULL} + * + * @param enumType the enum this constant belongs to + * @param enumConstant constant to transform + * + * @return the transformed constant - or the original value from the parameter if no transformation is needed. + * never return null + */ + String getEnumConstant(TypeElement enumType, String enumConstant); + + /** + * Return the type element of the exception that should be used in the generated code + * for an unexpected enum constant. + * + * @return the type element of the exception that should be used, never {@code null} + */ + TypeElement getUnexpectedValueMappingExceptionType(); +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/EnumTransformationStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/EnumTransformationStrategy.java new file mode 100644 index 0000000000..796bdb4954 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/EnumTransformationStrategy.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import org.mapstruct.util.Experimental; + +/** + * A service provider interface for transforming name based value mappings. + * + * @author Filip Hrisafov + * @since 1.4 + */ +@Experimental("This SPI can have its signature changed in subsequent releases") +public interface EnumTransformationStrategy { + + /** + * Initializes the enum transformation strategy with the MapStruct processing environment. + * + * @param processingEnvironment environment for facilities + */ + default void init(MapStructProcessingEnvironment processingEnvironment) { + + } + + /** + * The name of the strategy. + * + * @return the name of the strategy, never {@code null} + */ + String getStrategyName(); + + /** + * Transform the given value by using the given {@code configuration}. + * + * @param value the value that should be transformed + * @param configuration the configuration that should be used for the transformation + * + * @return the transformed value after applying the configuration + */ + String transform(String value, String configuration); +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/FreeBuilderAccessorNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/FreeBuilderAccessorNamingStrategy.java new file mode 100644 index 0000000000..dc14e20de6 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/FreeBuilderAccessorNamingStrategy.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import javax.lang.model.element.ExecutableElement; + +import org.mapstruct.util.Experimental; + +/** + * Accessor naming strategy for FreeBuilder. + * FreeBuilder adds a lot of other methods that can be considered as fluent setters. Such as: + *
        + *
      • {@code from(Target)}
      • + *
      • {@code mapXXX(UnaryOperator)}
      • + *
      • {@code mutateXXX(Consumer)}
      • + *
      • {@code mergeFrom(Target)}
      • + *
      • {@code mergeFrom(Target.Builder)}
      • + *
      + *

      + * When the JavaBean convention is not used with FreeBuilder then the getters are non-standard and MapStruct + * won't recognize them. Therefore, one needs to use the JavaBean convention in which the fluent setters + * start with {@code set}. + * + * @author Filip Hrisafov + */ +@Experimental("The FreeBuilder accessor naming strategy might change in a subsequent release") +public class FreeBuilderAccessorNamingStrategy extends DefaultAccessorNamingStrategy { + + @Override + protected boolean isFluentSetter(ExecutableElement method) { + // When using FreeBuilder one needs to use the JavaBean convention, which means that all setters will start + // with set + return false; + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesAccessorNamingStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesAccessorNamingStrategy.java index 5604220920..1df6ebc1b6 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesAccessorNamingStrategy.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesAccessorNamingStrategy.java @@ -1,36 +1,38 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; import javax.lang.model.element.ExecutableElement; +import org.mapstruct.util.Experimental; + /** - * Accesor naming strategy for Immutables. + * Accessor naming strategy for Immutables. * The generated Immutables also have a from that works as a copy. Our default strategy considers this method - * as a setter with a name {@code from}. Therefore we are ignoring it. + * as a setter with a name {@code from}. Therefore, we are ignoring it. * * @author Filip Hrisafov */ +@Experimental("The Immutables accessor naming strategy might change in a subsequent release") public class ImmutablesAccessorNamingStrategy extends DefaultAccessorNamingStrategy { @Override - protected boolean isBuilderSetter(ExecutableElement method) { - return super.isBuilderSetter( method ) && !method.getSimpleName().toString().equals( "from" ); + protected boolean isFluentSetter(ExecutableElement method) { + return super.isFluentSetter( method ) && + !method.getSimpleName().toString().equals( "from" ) && + !isPutterWithUpperCase4thCharacter( method ); } + + private boolean isPutterWithUpperCase4thCharacter(ExecutableElement method) { + return isPutterMethod( method ) && Character.isUpperCase( method.getSimpleName().toString().charAt( 3 ) ); + } + + public boolean isPutterMethod(ExecutableElement method) { + String methodName = method.getSimpleName().toString(); + return methodName.startsWith( "put" ) && methodName.length() > 3; + } + } diff --git a/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesBuilderProvider.java b/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesBuilderProvider.java index b02d4a9016..3431808418 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesBuilderProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/ImmutablesBuilderProvider.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; @@ -25,8 +12,8 @@ import javax.lang.model.element.Name; import javax.lang.model.element.PackageElement; import javax.lang.model.element.TypeElement; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; + +import org.mapstruct.util.Experimental; /** * Builder provider for Immutables. A custom provider is needed because Immutables creates an implementation of an @@ -36,40 +23,52 @@ * * @author Filip Hrisafov */ +@Experimental("The Immutables builder provider might change in a subsequent release") public class ImmutablesBuilderProvider extends DefaultBuilderProvider { private static final Pattern JAVA_JAVAX_PACKAGE = Pattern.compile( "^javax?\\..*" ); private static final String IMMUTABLE_FQN = "org.immutables.value.Value.Immutable"; @Override - protected BuilderInfo findBuilderInfo(TypeElement typeElement, Elements elements, Types types) { + protected BuilderInfo findBuilderInfo(TypeElement typeElement) { Name name = typeElement.getQualifiedName(); if ( name.length() == 0 || JAVA_JAVAX_PACKAGE.matcher( name ).matches() ) { return null; } - TypeElement immutableAnnotation = elements.getTypeElement( IMMUTABLE_FQN ); + + // First look if there is a builder defined in my own type + BuilderInfo info = findBuilderInfo( typeElement, false ); + if ( info != null ) { + return info; + } + + // Check for a builder in the generated immutable type + BuilderInfo immutableInfo = findBuilderInfoForImmutables( typeElement ); + if ( immutableInfo != null ) { + return immutableInfo; + } + + return super.findBuilderInfo( typeElement.getSuperclass() ); + } + + protected BuilderInfo findBuilderInfoForImmutables(TypeElement typeElement) { + TypeElement immutableAnnotation = elementUtils.getTypeElement( IMMUTABLE_FQN ); if ( immutableAnnotation != null ) { - BuilderInfo info = findBuilderInfoForImmutables( + return findBuilderInfoForImmutables( typeElement, - immutableAnnotation, - elements, - types + immutableAnnotation ); - if ( info != null ) { - return info; - } } - - return super.findBuilderInfo( typeElement, elements, types ); + return null; } protected BuilderInfo findBuilderInfoForImmutables(TypeElement typeElement, - TypeElement immutableAnnotation, Elements elements, Types types) { - for ( AnnotationMirror annotationMirror : elements.getAllAnnotationMirrors( typeElement ) ) { - if ( types.isSameType( annotationMirror.getAnnotationType(), immutableAnnotation.asType() ) ) { - TypeElement immutableElement = asImmutableElement( typeElement, elements ); + TypeElement immutableAnnotation) { + for ( AnnotationMirror annotationMirror : elementUtils.getAllAnnotationMirrors( typeElement ) ) { + if ( typeUtils.isSameType( annotationMirror.getAnnotationType(), immutableAnnotation.asType() ) ) { + TypeElement immutableElement = asImmutableElement( typeElement ); if ( immutableElement != null ) { - return super.findBuilderInfo( immutableElement, elements, types ); + return super.findBuilderInfo( immutableElement, false ); } else { // Immutables processor has not run yet. Trigger a postpone to the next round for MapStruct @@ -80,7 +79,7 @@ protected BuilderInfo findBuilderInfoForImmutables(TypeElement typeElement, return null; } - protected TypeElement asImmutableElement(TypeElement typeElement, Elements elements) { + protected TypeElement asImmutableElement(TypeElement typeElement) { Element enclosingElement = typeElement.getEnclosingElement(); StringBuilder builderQualifiedName = new StringBuilder( typeElement.getQualifiedName().length() + 17 ); if ( enclosingElement.getKind() == ElementKind.PACKAGE ) { @@ -95,6 +94,7 @@ protected TypeElement asImmutableElement(TypeElement typeElement, Elements eleme } builderQualifiedName.append( "Immutable" ).append( typeElement.getSimpleName() ); - return elements.getTypeElement( builderQualifiedName ); + return elementUtils.getTypeElement( builderQualifiedName ); } + } diff --git a/processor/src/main/java/org/mapstruct/ap/spi/MapStructProcessingEnvironment.java b/processor/src/main/java/org/mapstruct/ap/spi/MapStructProcessingEnvironment.java new file mode 100644 index 0000000000..18086e8591 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/MapStructProcessingEnvironment.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +import java.util.Map; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; + +/** + * MapStruct will provide the implementations of its SPIs with on object implementing this interface so they can use + * facilities provided by it. It is a subset of {@link javax.annotation.processing.ProcessingEnvironment + * ProcessingEnvironment}. + * + * @author Filip Hrisafov + * @see javax.annotation.processing.ProcessingEnvironment + * + * @since 1.3 + */ +public interface MapStructProcessingEnvironment { + + /** + * Returns an implementation of some utility methods for + * operating on elements + * + * @return element utilities + */ + Elements getElementUtils(); + + /** + * Returns an implementation of some utility methods for + * operating on types. + * + * @return type utilities + */ + Types getTypeUtils(); + + /** + * Returns the resolved options specified by the impl of + * {@link AdditionalSupportedOptionsProvider}. + * + * @return resolved options + */ + Map getOptions(); + +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/MappingExclusionProvider.java b/processor/src/main/java/org/mapstruct/ap/spi/MappingExclusionProvider.java index 98d329643f..2a1cacfb1f 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/MappingExclusionProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/MappingExclusionProvider.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; @@ -25,10 +12,9 @@ /** * A service provider interface that is used to control if MapStruct is allowed to generate automatic sub-mapping for * a given {@link TypeElement}. - * + *

      * When generating the implementation of a mapping method, MapStruct will apply the following routine for each * attribute pair in the source and target object: - * *

        *
      • If source and target attribute have the same type, the value will be simply copied from source to target. * If the attribute is a collection (e.g. a `List`) a copy of the collection will be set into the target @@ -43,14 +29,14 @@ *
      • If MapStruct could not create a name based mapping method an error will be raised at build time, * indicating the non-mappable attribute and its path.
      • *
      - * + *

      * With this SPI the last step before raising an error can be controlled. i.e. A user can control whether MapStruct * is allowed to generate such automatic sub-mapping method (for the source or target type) or not. * * @author Filip Hrisafov * @since 1.2 */ -@Experimental("This SPI can have it's signature changed in subsequent releases") +@Experimental("This SPI can have its signature changed in subsequent releases") public interface MappingExclusionProvider { /** @@ -59,7 +45,6 @@ public interface MappingExclusionProvider { * The given {@code typeElement} will be excluded from the automatic sub-mapping generation * * @param typeElement that needs to be checked - * * @return {@code true} if MapStruct should exclude the provided {@link TypeElement} from an automatic sub-mapping */ boolean isExcluded(TypeElement typeElement); diff --git a/processor/src/main/java/org/mapstruct/ap/spi/MethodType.java b/processor/src/main/java/org/mapstruct/ap/spi/MethodType.java index f61c3b86a5..d2b93e615e 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/MethodType.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/MethodType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; diff --git a/processor/src/main/java/org/mapstruct/ap/spi/MoreThanOneBuilderCreationMethodException.java b/processor/src/main/java/org/mapstruct/ap/spi/MoreThanOneBuilderCreationMethodException.java index 8d1038aa04..a869dd9fd6 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/MoreThanOneBuilderCreationMethodException.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/MoreThanOneBuilderCreationMethodException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; diff --git a/processor/src/main/java/org/mapstruct/ap/spi/NoOpBuilderProvider.java b/processor/src/main/java/org/mapstruct/ap/spi/NoOpBuilderProvider.java index b4c3cbe37f..a30346c4b0 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/NoOpBuilderProvider.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/NoOpBuilderProvider.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; // tag::documentation[] import javax.lang.model.type.TypeMirror; -import javax.lang.model.util.Elements; -import javax.lang.model.util.Types; // end::documentation[] @@ -35,8 +20,9 @@ public class NoOpBuilderProvider implements BuilderProvider { @Override - public BuilderInfo findBuilderInfo(TypeMirror type, Elements elements, Types types) { + public BuilderInfo findBuilderInfo(TypeMirror type) { return null; } + } // end::documentation[] diff --git a/processor/src/main/java/org/mapstruct/ap/spi/PrefixEnumTransformationStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/PrefixEnumTransformationStrategy.java new file mode 100644 index 0000000000..226251dfab --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/PrefixEnumTransformationStrategy.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +/** + * An {@link EnumTransformationStrategy} that prepends a prefix to the enum value. + * + * @author Filip Hrisafov + * + * @since 1.4 + */ +public class PrefixEnumTransformationStrategy implements EnumTransformationStrategy { + + @Override + public String getStrategyName() { + return "prefix"; + } + + @Override + public String transform(String value, String configuration) { + return configuration + value; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/StripPrefixEnumTransformationStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/StripPrefixEnumTransformationStrategy.java new file mode 100644 index 0000000000..dec7af6de4 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/StripPrefixEnumTransformationStrategy.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +/** + * An {@link EnumTransformationStrategy} that strips a prefix from the enum value. + * + * @author Filip Hrisafov + * + * @since 1.4 + */ +public class StripPrefixEnumTransformationStrategy implements EnumTransformationStrategy { + + @Override + public String getStrategyName() { + return "stripPrefix"; + } + + @Override + public String transform(String value, String configuration) { + if ( value.startsWith( configuration ) ) { + return value.substring( configuration.length() ); + } + return value; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/StripSuffixEnumTransformationStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/StripSuffixEnumTransformationStrategy.java new file mode 100644 index 0000000000..3b76354fa7 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/StripSuffixEnumTransformationStrategy.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +/** + * An {@link EnumTransformationStrategy} that strips a suffix from the enum value. + * + * @author Filip Hrisafov + * + * @since 1.4 + */ +public class StripSuffixEnumTransformationStrategy implements EnumTransformationStrategy { + + @Override + public String getStrategyName() { + return "stripSuffix"; + } + + @Override + public String transform(String value, String configuration) { + if ( value.endsWith( configuration ) ) { + return value.substring( 0, value.length() - configuration.length() ); + } + return value; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/SuffixEnumTransformationStrategy.java b/processor/src/main/java/org/mapstruct/ap/spi/SuffixEnumTransformationStrategy.java new file mode 100644 index 0000000000..1f4eb89217 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/SuffixEnumTransformationStrategy.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi; + +/** + * An {@link EnumTransformationStrategy} that appends a suffix to the enum value. + * + * @author Filip Hrisafov + * + * @since 1.4 + */ +public class SuffixEnumTransformationStrategy implements EnumTransformationStrategy { + + @Override + public String getStrategyName() { + return "suffix"; + } + + @Override + public String transform(String value, String configuration) { + return value + configuration; + } +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/TypeHierarchyErroneousException.java b/processor/src/main/java/org/mapstruct/ap/spi/TypeHierarchyErroneousException.java index c79ff31d01..aa9abc46a2 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/TypeHierarchyErroneousException.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/TypeHierarchyErroneousException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.spi; diff --git a/processor/src/main/java/org/mapstruct/ap/spi/package-info.java b/processor/src/main/java/org/mapstruct/ap/spi/package-info.java index b738b851cd..ca4ed5db3b 100644 --- a/processor/src/main/java/org/mapstruct/ap/spi/package-info.java +++ b/processor/src/main/java/org/mapstruct/ap/spi/package-info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ /** *

      diff --git a/processor/src/main/java/org/mapstruct/ap/spi/util/IntrospectorUtils.java b/processor/src/main/java/org/mapstruct/ap/spi/util/IntrospectorUtils.java new file mode 100644 index 0000000000..95dcd7a92d --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/util/IntrospectorUtils.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi.util; + +/** + * Utilities for tools to learn about the properties, events, and methods supported by a target Java Bean. + * It is mainly needed to avoid using {@link java.beans.Introspector} class which is part of java.desktop module + * from java 9, thus avoiding pulling a module ( of around 10 MB ) for using a single class. + * + * @author Saheb Preet Singh + */ +public class IntrospectorUtils { + + private IntrospectorUtils() { + } + + /** + * Utility method to take a string and convert it to normal Java variable + * name capitalization. This normally means converting the first + * character from upper case to lower case, but in the (unusual) special + * case when there is more than one character and both the first and + * second characters are upper case, we leave it alone. + *

      + * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays + * as "URL". + * + * @param name The string to be decapitalized. + * + * @return The decapitalized version of the string. + */ + public static String decapitalize(String name) { + if ( name == null || name.isEmpty() ) { + return name; + } + if ( name.length() > 1 && Character.isUpperCase( name.charAt( 1 ) ) && + Character.isUpperCase( name.charAt( 0 ) ) ) { + return name; + } + char[] chars = name.toCharArray(); + chars[0] = Character.toLowerCase( chars[0] ); + return new String( chars ); + } + +} diff --git a/processor/src/main/java/org/mapstruct/ap/spi/util/package-info.java b/processor/src/main/java/org/mapstruct/ap/spi/util/package-info.java new file mode 100644 index 0000000000..93bccf51d0 --- /dev/null +++ b/processor/src/main/java/org/mapstruct/ap/spi/util/package-info.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +/** + * Utility classes for the SPI package. + */ +package org.mapstruct.ap.spi.util; diff --git a/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors b/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors new file mode 100644 index 0000000000..172d1bb777 --- /dev/null +++ b/processor/src/main/resources/META-INF/gradle/incremental.annotation.processors @@ -0,0 +1 @@ +org.mapstruct.ap.MappingProcessor,isolating diff --git a/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor index 6ed0dfd63f..c472c18f91 100644 --- a/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor +++ b/processor/src/main/resources/META-INF/services/javax.annotation.processing.Processor @@ -1,18 +1,5 @@ -# Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) -# and/or other contributors as indicated by the @authors tag. See the -# copyright.txt file in the distribution for a full listing of all -# contributors. +# Copyright MapStruct Authors. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 org.mapstruct.ap.MappingProcessor diff --git a/processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor b/processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor index 61296cedec..d5234fca5b 100644 --- a/processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor +++ b/processor/src/main/resources/META-INF/services/org.mapstruct.ap.internal.processor.ModelElementProcessor @@ -1,22 +1,11 @@ -# Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) -# and/or other contributors as indicated by the @authors tag. See the -# copyright.txt file in the distribution for a full listing of all -# contributors. +# Copyright MapStruct Authors. # -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 org.mapstruct.ap.internal.processor.CdiComponentProcessor +org.mapstruct.ap.internal.processor.JakartaCdiComponentProcessor org.mapstruct.ap.internal.processor.Jsr330ComponentProcessor +org.mapstruct.ap.internal.processor.JakartaComponentProcessor org.mapstruct.ap.internal.processor.MapperCreationProcessor org.mapstruct.ap.internal.processor.MapperRenderingProcessor org.mapstruct.ap.internal.processor.MethodRetrievalProcessor diff --git a/processor/src/main/resources/META-INF/services/org.mapstruct.ap.spi.EnumTransformationStrategy b/processor/src/main/resources/META-INF/services/org.mapstruct.ap.spi.EnumTransformationStrategy new file mode 100644 index 0000000000..264b82d744 --- /dev/null +++ b/processor/src/main/resources/META-INF/services/org.mapstruct.ap.spi.EnumTransformationStrategy @@ -0,0 +1,9 @@ +# Copyright MapStruct Authors. +# +# Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +org.mapstruct.ap.spi.PrefixEnumTransformationStrategy +org.mapstruct.ap.spi.StripPrefixEnumTransformationStrategy +org.mapstruct.ap.spi.StripSuffixEnumTransformationStrategy +org.mapstruct.ap.spi.SuffixEnumTransformationStrategy +org.mapstruct.ap.spi.CaseEnumTransformationStrategy diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.ftl index 4c8894abf4..6753a73d6f 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/conversion/CreateDecimalFormat.ftl @@ -1,27 +1,14 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -private DecimalFormat ${name}( String numberFormat ) { +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> +private DecimalFormat ${name}( <#list parameters as param><@includeModel object=param/><#if param_has_next>, ) { - DecimalFormat df = new DecimalFormat( numberFormat ); + DecimalFormat df = new DecimalFormat( numberFormat<#if parameters.size() > 1>, DecimalFormatSymbols.getInstance( locale ) ); df.setParseBigDecimal( true ); return df; -} \ No newline at end of file +} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.ftl new file mode 100644 index 0000000000..6efbe7f0ff --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/conversion/GetDateTimeFormatterField.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingField" --> +private final <@includeModel object=type/> ${variableName} = <@includeModel object=type/>.ofPattern( "${templateParameter['dateFormat']}" ); \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedConstructor.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedConstructor.ftl index 78c3a76c4a..e3ddd51bd7 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedConstructor.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedConstructor.ftl @@ -1,35 +1,24 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.AnnotatedConstructor" --> -<#-- + <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> - -<#if publicEmptyConstructor> -public ${name}() { -} + <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.AnnotatedConstructor" --> + <#if noArgumentConstructor??> + <@includeModel object=noArgumentConstructor/> <#list annotations as annotation> <#nt><@includeModel object=annotation/> public ${name}(<#list mapperReferences as mapperReference><#list mapperReference.annotations as annotation><@includeModel object=annotation/> <@includeModel object=mapperReference.type/> ${mapperReference.variableName}<#if mapperReference_has_next>, ) { + <#if noArgumentConstructor?? && !noArgumentConstructor.fragments.empty>this(); <#list mapperReferences as mapperReference> this.${mapperReference.variableName} = ${mapperReference.variableName}; + <#list fragments as fragment> + <#nt><@includeModel object=fragment/> + } \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedSetter.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedSetter.ftl new file mode 100644 index 0000000000..74d4241fa5 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotatedSetter.ftl @@ -0,0 +1,14 @@ + <#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> + <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.AnnotatedSetter" --> + <#list methodAnnotations as annotation> + <#nt><@includeModel object=annotation/> + +public void set${fieldName?cap_first}(<#list parameterAnnotations as annotation><#nt><@includeModel object=annotation/> <@includeModel object=type/> ${fieldName}) { + this.${fieldName} = ${fieldName}; +} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/Annotation.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/Annotation.ftl index 2be168662c..0b6737fbe4 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/Annotation.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/Annotation.ftl @@ -1,22 +1,20 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.Annotation" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -@<@includeModel object=type/><#if (properties?size > 0) >(<#list properties as property>${property}<#if property_has_next>, ) \ No newline at end of file +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.Annotation" --> +<#switch properties?size> + <#on 0> + @<@includeModel object=type/><#rt> + <#on 1> + @<@includeModel object=type/>(<@includeModel object=properties[0]/>)<#rt> + <#default> + @<@includeModel object=type/>( + <#list properties as property> + <#nt><@includeModel object=property/><#if property_has_next>, + + )<#rt> + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotationMapperReference.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotationMapperReference.ftl index ac42d221e3..616c4900e6 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotationMapperReference.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/AnnotationMapperReference.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.AnnotationMapperReference" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.AnnotationMapperReference" --> <#if includeAnnotationsOnField> <#list annotations as annotation> <#nt><@includeModel object=annotation/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl index 6bba770a78..fd101f0d95 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/BeanMappingMethod.ftl @@ -1,29 +1,18 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.BeanMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<#if overridden>@Override +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.BeanMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#assign targetType = resultType /> <#if !existingInstanceMapping> - <#assign targetType = resultType.effectiveType /> + <#assign targetType = returnTypeToConstruct /> <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=targetType/> @@ -31,14 +20,94 @@ - <#if !mapNullToDefault> - if ( <#list sourceParametersExcludingPrimitives as sourceParam>${sourceParam.name} == null<#if sourceParam_has_next> && ) { - return<#if returnType.name != "void"> null; + <#list beforeMappingReferencesWithFinalizedReturnType as callback> + <@includeModel object=callback targetBeanName=finalizedResultName targetType=finalizedReturnType/> + <#if !callback_has_next> + + + + <#if !mapNullToDefault && !sourcePresenceChecks.empty> + if ( <#list sourcePresenceChecks as sourcePresenceCheck><@includeModel object=sourcePresenceCheck.negate() /><#if sourcePresenceCheck_has_next> && ) { + <#if returnType.name == "void"> + return; + <#else> + <#if existingInstanceMapping> + <@createReturn applyOptionalAfterMapping=false>${resultName}<#if finalizerMethod??>.<@includeModel object=finalizerMethod /> + <#else> + return ${returnType.null}; + + } + <#if hasSubclassMappings()> + <#list subclassMappings as subclass> + <#if subclass_index > 0>else if (${subclass.sourceArgument} instanceof <@includeModel object=subclass.sourceType/>) { + <@includeModel object=subclass.assignment existingInstanceMapping=existingInstanceMapping/> + } + + else { + + <#if isAbstractReturnType()> + throw new <@includeModel object=subclassExhaustiveException />("Not all subclasses are supported for this mapping. Missing for " + ${subclassMappings[0].sourceArgument}.getClass()); + <#else> <#if !existingInstanceMapping> - <@includeModel object=resultType.effectiveType/> ${resultName} = <#if factoryMethod??><@includeModel object=factoryMethod targetType=resultType.effectiveType/><#else>new <@includeModel object=resultType.effectiveType/>(); + <#if hasConstructorMappings()> + <#if (sourceParameters?size > 1)> + <#list sourceParametersNeedingPresenceCheck as sourceParam> + <#if (constructorPropertyMappingsByParameter(sourceParam)?size > 0)> + <#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping> + <@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null}; + + if ( <@includeModel object=getPresenceCheckByParameter(sourceParam) /> ) { + <#assign sourceParamReassignment = getSourceParameterReassignment(sourceParam)!'' /> + <#if sourceParamReassignment?has_content> + <@includeModel object=sourceParamReassignment.type /> ${sourceParamReassignment.name} = ${sourceParam.name}.get(); + + + <#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping> + <@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> + + } + + + <#list sourceParametersNotNeedingPresenceCheck as sourceParam> + <#if (constructorPropertyMappingsByParameter(sourceParam)?size > 0)> + <#list constructorPropertyMappingsByParameter(sourceParam) as propertyMapping> + <@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null}; + <@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> + + + + <#else> + <#list constructorPropertyMappingsByParameter(sourceParameters[0]) as propertyMapping> + <@includeModel object=propertyMapping.targetType /> ${propertyMapping.targetWriteAccessorName} = ${propertyMapping.targetType.null}; + + <#if mapNullToDefault>if ( <@includeModel object=getPresenceCheckByParameter(sourceParameters[0]) /> ) { + <#assign sourceParamReassignment = getSourceParameterReassignment(sourceParameters[0])!'' /> + <#if sourceParamReassignment?has_content> + <@includeModel object=sourceParamReassignment.type /> ${sourceParamReassignment.name} = ${sourceParameters[0].name}.get(); + + + <#list constructorPropertyMappingsByParameter(sourceParameters[0]) as propertyMapping> + <@includeModel object=propertyMapping existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> + + <#if mapNullToDefault> + } + + + <#list constructorConstantMappings as constantMapping> + + <@compress single_line=true> + <@includeModel object=constantMapping.targetType /> <@includeModel object=constantMapping existingInstanceMapping=existingInstanceMapping/> + + + + + <@includeModel object=returnTypeToConstruct/> ${resultName} = <@includeModel object=factoryMethod targetType=returnTypeToConstruct/>; + <#else > + <@includeModel object=returnTypeToConstruct/> ${resultName} = <#if factoryMethod??><@includeModel object=factoryMethod targetType=returnTypeToConstruct/><#else><@includeModel object=newInstance/>(); + <#list beforeMappingReferencesWithMappingTarget as callback> @@ -48,24 +117,34 @@ <#if (sourceParameters?size > 1)> - <#list sourceParametersExcludingPrimitives as sourceParam> + <#list sourceParametersNeedingPresenceCheck as sourceParam> <#if (propertyMappingsByParameter(sourceParam)?size > 0)> - if ( ${sourceParam.name} != null ) { + if ( <@includeModel object=getPresenceCheckByParameter(sourceParam) /> ) { + <#assign sourceParamReassignment = getSourceParameterReassignment(sourceParam)!'' /> + <#if sourceParamReassignment?has_content> + <@includeModel object=sourceParamReassignment.type /> ${sourceParamReassignment.name} = ${sourceParam.name}.get(); + + <#list propertyMappingsByParameter(sourceParam) as propertyMapping> <@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> } - <#list sourcePrimitiveParameters as sourceParam> + <#list sourceParametersNotNeedingPresenceCheck as sourceParam> <#if (propertyMappingsByParameter(sourceParam)?size > 0)> <#list propertyMappingsByParameter(sourceParam) as propertyMapping> <@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> - <#else> - <#if mapNullToDefault>if ( ${sourceParameters[0].name} != null ) { + <#elseif !propertyMappingsByParameter(sourceParameters[0]).empty> + <#if mapNullToDefault>if ( <@includeModel object=getPresenceCheckByParameter(sourceParameters[0]) /> ) { + <#assign sourceParamReassignment = getSourceParameterReassignment(sourceParameters[0])!'' /> + <#if sourceParamReassignment?has_content> + <@includeModel object=sourceParamReassignment.type /> ${sourceParamReassignment.name} = ${sourceParameters[0].name}.get(); + + <#list propertyMappingsByParameter(sourceParameters[0]) as propertyMapping> <@includeModel object=propertyMapping targetBeanName=resultName existingInstanceMapping=existingInstanceMapping defaultValueAssignment=propertyMapping.defaultValueAssignment/> @@ -82,11 +161,28 @@ <#if returnType.name != "void"> - <#if finalizerMethod??> - return ${resultName}.<@includeModel object=finalizerMethod />; - <#else> - return ${resultName}; + <#if finalizerMethod??> + <#if (afterMappingReferencesWithFinalizedReturnType?size > 0)> + <@includeModel object=finalizedReturnType /> ${finalizedResultName} = ${resultName}.<@includeModel object=finalizerMethod />; + + <#list afterMappingReferencesWithFinalizedReturnType as callback> + <#if callback_index = 0> + + + <@includeModel object=callback targetBeanName=finalizedResultName targetType=finalizedReturnType/> + + + <@createReturn>${finalizedResultName} + <#else> + <@createReturn>${resultName}.<@includeModel object=finalizerMethod /> + + <#else> + <@createReturn>${resultName} + + + <#if hasSubclassMappings()> + } } <#macro throws> @@ -96,4 +192,27 @@ <#if exceptionType_has_next>, <#t> + +<#macro createReturn applyOptionalAfterMapping=true> +<#-- <@compress single_line=true>--> + <#if returnType.optionalType> + <#if (afterMappingReferencesWithOptionalReturnType?size > 0)> + <@includeModel object=returnType /> ${optionalResultName} = <@includeModel object=returnType.asRawType()/>.of( <#nested/> ); + + <#list afterMappingReferencesWithOptionalReturnType as callback> + <#if callback_index = 0> + + + <@includeModel object=callback targetBeanName=optionalResultName targetType=returnType/> + + + return ${optionalResultName}; + <#else> + return <@includeModel object=returnType.asRawType()/>.of( <#nested/> ); + + <#else> + return <#nested/>; + +<#-- --> + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ConversionMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ConversionMethod.ftl index f62ee1bf27..14d0e4883d 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ConversionMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ConversionMethod.ftl @@ -1,21 +1,8 @@ <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> ${name}<#if ext.input??>( ${ext.input} )<#else>() \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/DecoratorConstructor.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/DecoratorConstructor.ftl index 46dee8b6ef..9c9f397c29 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/DecoratorConstructor.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/DecoratorConstructor.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DecoratorConstructor" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DecoratorConstructor" --> public ${name}() { this( new ${delegateName}() ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/DefaultMapperReference.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/DefaultMapperReference.ftl index 034a5ff812..b2ab4cb6f0 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/DefaultMapperReference.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/DefaultMapperReference.ftl @@ -1,22 +1,9 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DefaultMapperReference" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -private final <@includeModel object=type/> ${variableName} = <#if annotatedMapper>Mappers.getMapper( <@includeModel object=type/>.class );<#else>new <@includeModel object=type/>(); \ No newline at end of file +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DefaultMapperReference" --> +private final <@includeModel object=type/> ${variableName} = <#if singleton><@includeModel object=type/>.INSTANCE;<#else><#if annotatedMapper>Mappers.getMapper( <@includeModel object=type/>.class );<#else>new <@includeModel object=type/>(); \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/DelegatingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/DelegatingMethod.ftl index bdbc8f3829..f27c242de1 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/DelegatingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/DelegatingMethod.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DelegatingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.DelegatingMethod" --> @Override public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) <@throws/> { <#if returnType.name != "void">return delegate.${name}( <#list parameters as param>${param.name}<#if param_has_next>, ); diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/EnumMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/EnumMappingMethod.ftl deleted file mode 100644 index 628d760fc6..0000000000 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/EnumMappingMethod.ftl +++ /dev/null @@ -1,57 +0,0 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.EnumMappingMethod" --> -<#-- - - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - ---> -@Override -public <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) { - <#list beforeMappingReferencesWithoutMappingTarget as callback> - <@includeModel object=callback targetBeanName=resultName targetType=resultType/> - <#if !callback_has_next> - - - - if ( ${sourceParameter.name} == null ) { - return null; - } - - <@includeModel object=resultType/> ${resultName}; - - switch ( ${sourceParameter.name} ) { - <#list enumMappings as enumMapping> - case ${enumMapping.source}: ${resultName} = <@includeModel object=returnType/>.${enumMapping.target}; - break; - - default: throw new IllegalArgumentException( "Unexpected enum constant: " + ${sourceParameter.name} ); - } - <#list beforeMappingReferencesWithMappingTarget as callback> - <#if callback_index = 0> - - - <@includeModel object=callback targetBeanName=resultName targetType=resultType/> - - <#list afterMappingReferences as callback> - <#if callback_index = 0> - - - <@includeModel object=callback targetBeanName=resultName targetType=resultType/> - - - return ${resultName}; -} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/Field.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/Field.ftl index a21e77fecd..af4cb01f63 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/Field.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/Field.ftl @@ -1,22 +1,9 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.Field" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.Field" --> private final <@includeModel object=type/> ${variableName}; \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/FromOptionalTypeConversion.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/FromOptionalTypeConversion.ftl new file mode 100644 index 0000000000..50ab97e5b4 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/FromOptionalTypeConversion.ftl @@ -0,0 +1,16 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.FromOptionalTypeConversion" --> +<@includeModel object=assignment + targetBeanName=ext.targetBeanName + existingInstanceMapping=ext.existingInstanceMapping + targetReadAccessorName=ext.targetReadAccessorName + targetWriteAccessorName=ext.targetWriteAccessorName + sourcePropertyName=ext.sourcePropertyName + targetPropertyName=ext.targetPropertyName + targetType=ext.targetType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/GeneratedType.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/GeneratedType.ftl index 0656686b4f..c65b3e5f85 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/GeneratedType.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/GeneratedType.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.GeneratedType" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.GeneratedType" --> <#if hasPackageName()> package ${packageName}; @@ -27,6 +14,7 @@ package ${packageName}; import ${importedType}; +<#if javadoc??><#nt><@includeModel object=javadoc/> <#if !generatedTypeAvailable>/* @Generated( value = "org.mapstruct.ap.MappingProcessor"<#if suppressGeneratorTimestamp == false>, @@ -37,7 +25,7 @@ import ${importedType}; <#list annotations as annotation> <#nt><@includeModel object=annotation/> -<#lt>${accessibility.keyword} class ${name}<#if superClassName??> extends ${superClassName}<#if interfaceName??> implements ${interfaceName} { +<#lt>${accessibility.keyword} class ${name} <#if mapperDefinitionType.interface>implements<#else>extends <@includeModel object=mapperDefinitionType/> { <#list fields as field><#if field.used><#nt> <@includeModel object=field/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableCreation.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableCreation.ftl index 5c3f95c49c..aff9641d60 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableCreation.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableCreation.ftl @@ -1,34 +1,25 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableCreation" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableCreation" --> <@compress single_line=true> <#if factoryMethod??> <@includeModel object=factoryMethod targetType=resultType/> - <#else> - new - <#if resultType.implementationType??> - <@includeModel object=resultType.implementationType/><#if ext.useSizeIfPossible?? && ext.useSizeIfPossible && canUseSize>( <@sizeForCreation /> )<#else>() + <#elseif enumSet> + EnumSet.noneOf( <@includeModel object=enumSetElementType raw=true/>.class ) + <#elseif resultType.implementation??> + <#if resultType.implementation.factoryMethodName?? && ext.useSizeIfPossible?? && ext.useSizeIfPossible && canUseSize> + <@includeModel object=resultType.implementationType raw=true />.${resultType.implementation.factoryMethodName}( <@sizeForCreation /> ) <#else> - <@includeModel object=resultType/>() + <@includeModel object=newInstance/><#if ext.useSizeIfPossible?? && ext.useSizeIfPossible && canUseSize>( <@sizeForCreation /> )<#else>() + <#else> + <@includeModel object=newInstance/>() + <#macro sizeForCreation> <@compress single_line=true> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl index 3e404ede61..6268366f7b 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/IterableMappingMethod.ftl @@ -1,25 +1,15 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<#if overridden>@Override +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.IterableMappingMethod" --> +<#import "macro/CommonMacros.ftl" as lib> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> @@ -27,10 +17,10 @@ - if ( ${sourceParameter.name} == null ) { + <#if sourceParameterPresenceCheck??> + if ( <@includeModel object=sourceParameterPresenceCheck.negate() /> ) { <#if !mapNullToDefault> - <#-- returned target type starts to miss-align here with target handed via param, TODO is this right? --> - return<#if returnType.name != "void"> null; + return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null; <#else> <#if resultType.arrayType> <#if existingInstanceMapping> @@ -40,7 +30,7 @@ } return<#if returnType.name != "void"> ${resultName}; <#else> - return new <@includeModel object=resultElementType/>[0]; + return <@lib.constructArrayType targetType=resultType targetSize=0/>; <#else> <#if existingInstanceMapping> @@ -52,11 +42,11 @@ } + <#if resultType.arrayType> <#if !existingInstanceMapping> - <#assign elementTypeString><@includeModel object=resultElementType/> - ${elementTypeString}[] ${resultName} = new ${elementTypeString?keep_before('[]')}[<@iterableSize/>]${elementTypeString?replace('[^\\[\\]]+', '', 'r')}; + <@includeModel object=resultElementType/>[] ${resultName} = <@lib.constructArrayType targetType=resultType targetSize=iterableSize()/>; <#else> <#if existingInstanceMapping> @@ -76,7 +66,7 @@ int ${index1Name} = 0; for ( <@includeModel object=sourceElementType/> ${loopVariableName} : ${sourceParameter.name} ) { <#if existingInstanceMapping> - if ( ( ${index1Name} >= ${resultName}.length ) || ( ${index1Name} >= <@iterableSize/> ) ) { + if ( ( ${index1Name} >= ${resultName}.length ) || ( ${index1Name} >= ${iterableSize()} ) ) { break; } @@ -107,15 +97,13 @@ -<#macro iterableSize> - <@compress single_line=true> - <#if sourceParameter.type.arrayType> - ${sourceParameter.name}.length - <#else> - ${sourceParameter.name}.size() - - - +<#function iterableSize> + <#if sourceParameter.type.arrayType> + <#return sourceParameter.name + ".length"> + <#else> + <#return sourceParameter.name + ".size()"> + + <#macro iterableLocalVarDef> <@compress single_line=true> <#if resultType.fullyQualifiedName == "java.lang.Iterable"> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/Javadoc.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/Javadoc.ftl new file mode 100644 index 0000000000..89ac57b9ef --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/Javadoc.ftl @@ -0,0 +1,25 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.Javadoc" --> +/** +<#list value?split("\n") as line><#nt>*<#if line?has_content> ${line?trim} + +<#if !authors.isEmpty()> +* +<#list authors as author> <#nt>* @author ${author?trim} + + +<#if deprecated?has_content> +* +<#nt>* @deprecated ${deprecated?trim} + +<#if since?has_content> +* +<#nt>* @since ${since?trim} + +<#nt> */ \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.ftl index e34de1733b..310eda210d 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/LifecycleCallbackMethodReference.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.LifecycleCallbackMethodReference" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.LifecycleCallbackMethodReference" --> <@compress single_line=true> <#if hasReturnType()> <@includeModel object=methodResultType /> ${targetVariableName} = diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl index ed6d903006..e04d1b9475 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MapMappingMethod.ftl @@ -1,25 +1,14 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<#if overridden>@Override +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MapMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType /> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> @@ -27,9 +16,10 @@ - if ( ${sourceParameter.name} == null ) { + <#if sourceParameterPresenceCheck??> + if ( <@includeModel object=sourceParameterPresenceCheck.negate() /> ) { <#if !mapNullToDefault> - return<#if returnType.name != "void"> null; + return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null; <#else> <#if existingInstanceMapping> ${resultName}.clear(); @@ -39,6 +29,7 @@ } + <#if existingInstanceMapping> ${resultName}.clear(); diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReference.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReference.ftl index 8f4a31ddc6..63f983df46 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReference.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReference.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MethodReference" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MethodReference" --> <@compress single_line=true> <#-- method is either internal to the mapper class, or external (via uses) declaringMapper!=null --> <#if declaringMapper??> @@ -28,7 +15,11 @@ <#if static><@includeModel object=providingParameter.type/><#else>${providingParameter.name}.<@methodCall/> <#-- method is referenced java8 static method in the mapper to implement (interface) --> <#elseif static> - <@includeModel object=definingType/>.<@methodCall/> + <@includeModel object=definingType raw=true/>.<@methodCall/> + <#elseif constructor> + new <@includeModel object=definingType/><#if (parameterBindings?size > 0)>( <@arguments/> )<#else>() + <#elseif methodChaining> + <#list methodsToChain as methodToChain><@includeModel object=methodToChain /><#if methodToChain_has_next>. <#else> <@methodCall/> @@ -48,11 +39,15 @@ <#list parameterBindings as param> <#if param.targetType> <#-- a class is passed on for casting, see @TargetType --> - <@includeModel object=ext.targetType raw=true/>.class<#t> + <@includeModel object=inferTypeWhenEnum( ext.targetType ) raw=true/>.class<#t> <#elseif param.mappingTarget> - ${ext.targetBeanName}<#if ext.targetReadAccessorName??>.${ext.targetReadAccessorName}<#t> + <#if ext.targetBeanName??>${ext.targetBeanName}<#else>${param.variableName}<#if ext.targetReadAccessorName??>.${ext.targetReadAccessorName}<#t> <#elseif param.mappingContext> ${param.variableName}<#t> + <#elseif param.sourcePropertyName> + "${ext.sourcePropertyName}"<#t> + <#elseif param.targetPropertyName> + "${ext.targetPropertyName}"<#t> <#elseif param.sourceRHS??> <@_assignment assignmentToUse=param.sourceRHS/><#t> <#elseif assignment??> @@ -67,13 +62,16 @@ <#-- macro: assignment - purpose: note: takes its targetyType from the singleSourceParameterType + purpose: note: takes its targetType from the singleSourceParameterType --> <#macro _assignment assignmentToUse> <@includeModel object=assignmentToUse + presenceCheck=ext.presenceCheck targetBeanName=ext.targetBeanName existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName + sourcePropertyName=ext.sourcePropertyName + targetPropertyName=ext.targetPropertyName targetType=singleSourceParameterType/> - \ No newline at end of file + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReferencePresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReferencePresenceCheck.ftl new file mode 100644 index 0000000000..68b05d84ed --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/MethodReferencePresenceCheck.ftl @@ -0,0 +1,13 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.MethodReferencePresenceCheck" --> +<#if isNegate()>!<@includeModel object=methodReference + presenceCheck=true + sourcePropertyName=ext.sourcePropertyName + targetPropertyName=ext.targetPropertyName + targetType=ext.targetType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl index 337c6d5564..04d385a9dc 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/NestedPropertyMappingMethod.ftl @@ -1,48 +1,25 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.NestedPropertyMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<#lt>private <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { - if ( ${sourceParameter.name} == null ) { - return ${returnType.null}; - } +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.NestedPropertyMappingMethod" --> +<#lt>private <@includeModel object=returnType.typeBound/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list propertyEntries as entry> - <#if entry.presenceCheckerName?? > - if ( !<@localVarName index=entry_index/>.${entry.presenceCheckerName}() ) { + <#if entry.presenceChecker?? > + if ( <@includeModel object=entry.presenceChecker /> ) { return ${returnType.null}; } - <@includeModel object=entry.type/> ${entry.name} = <@localVarName index=entry_index/>.${entry.accessorName}; - <#if !entry.presenceCheckerName?? > - <#if !entry.type.primitive> - if ( ${entry.name} == null ) { - return ${returnType.null}; - } - - - <#if !entry_has_next> - return ${entry.name}; + <#if entry_has_next> + <@includeModel object=entry.type.typeBound/> ${entry.name} = ${entry.source}; + <#else> + return ${entry.source}; } -<#macro localVarName index><#if index == 0>${sourceParameter.name}<#else>${propertyEntries[index-1].name} <#macro throws> <#if (thrownTypes?size > 0)><#lt> throws <@compress single_line=true> <#list thrownTypes as exceptionType> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/NoArgumentConstructor.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/NoArgumentConstructor.ftl new file mode 100644 index 0000000000..e0ae1454b7 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/NoArgumentConstructor.ftl @@ -0,0 +1,13 @@ + <#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> + <#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.NoArgumentConstructor" --> +public ${name}() { + <#list fragments as fragment> + <#nt><@includeModel object=fragment/> + + } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/PropertyMapping.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/PropertyMapping.ftl index 86a623e177..f45659cb5d 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/PropertyMapping.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/PropertyMapping.ftl @@ -1,28 +1,17 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.PropertyMapping" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.PropertyMapping" --> <@includeModel object=assignment targetBeanName=ext.targetBeanName existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=targetReadAccessorName targetWriteAccessorName=targetWriteAccessorName + sourcePropertyName=sourcePropertyName + targetPropertyName=name targetType=targetType defaultValueAssignment=defaultValueAssignment /> \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ServicesEntry.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ServicesEntry.ftl index 1963e84eb2..facbb5f8b7 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ServicesEntry.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ServicesEntry.ftl @@ -1,22 +1,9 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ServicesEntry" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ServicesEntry" --> ${implementationPackage}.${implementationName} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl index f8877a02e5..0f335f9c54 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/StreamMappingMethod.ftl @@ -1,25 +1,15 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<#if overridden>@Override +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.StreamMappingMethod" --> +<#import "macro/CommonMacros.ftl" as lib> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#--TODO does it even make sense to do a callback if the result is a Stream, as they are immutable--> <#list beforeMappingReferencesWithoutMappingTarget as callback> @@ -28,10 +18,10 @@ - if ( ${sourceParameter.name} == null ) { + <#if sourceParameterPresenceCheck??> + if ( <@includeModel object=sourceParameterPresenceCheck.negate() /> ) { <#if !mapNullToDefault> - <#-- returned target type starts to miss-align here with target handed via param, TODO is this right? --> - return<#if returnType.name != "void"> null; + return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null; <#else> <#if resultType.arrayType> <#if existingInstanceMapping> @@ -41,7 +31,7 @@ } return<#if returnType.name != "void"> ${resultName}; <#else> - return new <@includeModel object=resultElementType/>[0]; + return <@lib.constructArrayType targetType=resultType targetSize=0/>; <#elseif resultType.iterableType> <#if existingInstanceMapping> @@ -60,15 +50,16 @@ } + - <#-- A variable needs to be defined if there are before mappings and this is not exisitingInstanceMapping --> - <#assign needVarDefine = beforeMappingReferencesWithMappingTarget?has_content && !existingInstanceMapping /> + <#-- A variable needs to be defined if there are before or after mappings and this is not exisitingInstanceMapping --> + <#assign needVarDefine = (beforeMappingReferencesWithMappingTarget?has_content || afterMappingReferences?has_content) && !existingInstanceMapping /> <#if resultType.arrayType> - <#if !existingInstanceMapping && needVarDefine> + <#if needVarDefine> <#assign needVarDefine = false /> <#-- We create a null array which later will be directly assigned from the stream--> - ${resultElementType}[] ${resultName} = null; + <@includeModel object=resultElementType/>[] ${resultName} = null; <#elseif resultType.iterableType> <#if existingInstanceMapping> @@ -80,7 +71,7 @@ <#else> <#-- Streams are immutable so we can't update them --> - <#if !existingInstanceMapping && needVarDefine> + <#if needVarDefine> <#assign needVarDefine = false /> <@iterableLocalVarDef/> ${resultName} = Stream.empty(); @@ -100,7 +91,7 @@ <#if resultType.arrayType> <#if existingInstanceMapping> int ${index1Name} = 0; - for ( <@includeModel object=resultElementType/> ${loopVariableName} : ${sourceParameter.name}.limit( ${resultName}.length )<@streamMapSupplier />.toArray( ${resultElementType}[]::new ) ) { + for ( <@includeModel object=resultElementType/> ${loopVariableName} : ${sourceParameter.name}.limit( ${resultName}.length )<@streamMapSupplier />.toArray( <@includeModel object=resultElementType raw=true/>[]::new ) ) { if ( ( ${index1Name} >= ${resultName}.length ) ) { break; } @@ -108,7 +99,7 @@ } <#else> <#if canReturnImmediatelly><#if returnType.name != "void">return <#else> <#if needVarDefine>${resultElementType}[] <#else>${resultName} = ${sourceParameter.name}<@streamMapSupplier /> - .toArray( <@includeModel object=resultElementType/>[]::new ); + .toArray( <@includeModel object=resultElementType raw=true/>[]::new ); <#elseif resultType.iterableType> <#if existingInstanceMapping || !canReturnImmediatelly> @@ -125,7 +116,7 @@ <#else> <#-- Streams are immutable so we can't update them --> <#if !existingInstanceMapping> - <#--TODO fhr: after the the result is no longer the same instance, how does it affect the + <#--TODO fhr: after the result is no longer the same instance, how does it affect the Before mapping methods. Does it even make sense to have before mapping on a stream? --> <#if sourceParameter.type.arrayType> <@returnLocalVarDefOrUpdate>Stream.of( ${sourceParameter.name} )<@streamMapSupplier />; @@ -193,5 +184,5 @@ <#macro returnLocalVarDefOrUpdate> - <#if canReturnImmediatelly><#if returnType.name != "void">return <#elseif !needVarDefine><@iterableLocalVarDef/> ${resultName} = <#else>${resultName} = <#nested /> + <#if canReturnImmediatelly><#if returnType.name != "void">return <#elseif needVarDefine><@iterableLocalVarDef/> ${resultName} = <#else>${resultName} = <#nested /> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ToOptionalTypeConversion.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ToOptionalTypeConversion.ftl new file mode 100644 index 0000000000..48e20e7017 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ToOptionalTypeConversion.ftl @@ -0,0 +1,21 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ToOptionalTypeConversion" --> +<@compress single_line=true> +<@includeModel object=targetType.asRawType() />.of( <@_assignment/> ) +<#macro _assignment> + <@includeModel object=assignment + targetBeanName=ext.targetBeanName + existingInstanceMapping=ext.existingInstanceMapping + targetReadAccessorName=ext.targetReadAccessorName + targetWriteAccessorName=ext.targetWriteAccessorName + sourcePropertyName=ext.sourcePropertyName + targetPropertyName=ext.targetPropertyName + targetType=ext.targetType/> + + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/TypeConversion.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/TypeConversion.ftl index b9469b048a..a5e5798d1c 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/TypeConversion.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/TypeConversion.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.TypeConversion" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.TypeConversion" --> <@compress single_line=true> ${openExpression}<@_assignment/>${closeExpression} <#macro _assignment> @@ -27,6 +14,8 @@ ${openExpression}<@_assignment/>${closeExpression} existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName + sourcePropertyName=ext.sourcePropertyName + targetPropertyName=ext.targetPropertyName targetType=ext.targetType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl index 9163417f2c..224b6c3dfa 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/ValueMappingMethod.ftl @@ -1,26 +1,16 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ValueMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.ValueMappingMethod" --> +<#list annotations as annotation> + <#nt><@includeModel object=annotation/> + <#if overridden>@Override -<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, ) { +<#lt>${accessibility.keyword} <@includeModel object=returnType/> ${name}(<#list parameters as param><@includeModel object=param/><#if param_has_next>, )<@throws/> { <#list beforeMappingReferencesWithoutMappingTarget as callback> <@includeModel object=callback targetBeanName=resultName targetType=resultType/> <#if !callback_has_next> @@ -28,18 +18,38 @@ if ( ${sourceParameter.name} == null ) { - return <#if nullTarget??><@includeModel object=returnType/>.${nullTarget}<#else>null; + <#if nullTarget.targetAsException>throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} );<#else>return <@writeTarget target=nullTarget.target/>; } - <@includeModel object=resultType/> ${resultName}; + <#if versionInformation.isSourceVersionAtLeast14()> + <#if valueMappings.empty> + <#if defaultTarget.targetAsException> + <@includeModel object=resultType/> ${resultName}; + throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} ); + <#else> + <@includeModel object=resultType/> ${resultName} = <@writeTarget target=defaultTarget.target/>; + + <#else> + <@includeModel object=resultType/> ${resultName} = switch ( ${sourceParameter.name} ) { + <#list valueMappings as valueMapping> + case <@writeSource source=valueMapping.source/> -> <#if valueMapping.targetAsException > throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} );<#else><@writeTarget target=valueMapping.target/>; + + <#if isDefaultTargetRequired()> + default -> <#if defaultTarget.targetAsException>throw new <@includeModel object=unexpectedValueMappingException/>( "Unexpected enum constant: " + ${sourceParameter.name} )<#else><@writeTarget target=defaultTarget.target/>; + + }; + + <#else> + <@includeModel object=resultType/> ${resultName}; - switch ( ${sourceParameter.name} ) { - <#list valueMappings as valueMapping> - case ${valueMapping.source}: ${resultName} = <#if valueMapping.target??><@includeModel object=returnType/>.${valueMapping.target}<#else>null; - break; - - default: <#if throwIllegalArgumentException>throw new IllegalArgumentException( "Unexpected enum constant: " + ${sourceParameter.name} )<#else>${resultName} = <#if defaultTarget??><@includeModel object=returnType/>.${defaultTarget}<#else>null; - } + switch ( ${sourceParameter.name} ) { + <#list valueMappings as valueMapping> + case <@writeSource source=valueMapping.source/>: <#if valueMapping.targetAsException >throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} );<#else>${resultName} = <@writeTarget target=valueMapping.target/>; + break; + + default: <#if defaultTarget.targetAsException >throw new <@includeModel object=unexpectedValueMappingException />( "Unexpected enum constant: " + ${sourceParameter.name} )<#else>${resultName} = <@writeTarget target=defaultTarget.target/>; + } + <#list beforeMappingReferencesWithMappingTarget as callback> <#if callback_index = 0> @@ -53,5 +63,33 @@ <@includeModel object=callback targetBeanName=resultName targetType=resultType/> + <#if !(valueMappings.empty && defaultTarget.targetAsException)> return ${resultName}; + } +<#macro writeSource source=""> + <#if sourceParameter.type.enumType> + ${source}<#t> + <#elseif sourceParameter.type.string> + "${source}"<#t> + + +<#macro writeTarget target=""> + <#if target?has_content> + <#if returnType.enumType> + <@includeModel object=returnType/>.${target}<#t> + <#elseif returnType.string> + "${target}"<#t> + + <#else> + null<#t> + + +<#macro throws> + <#if (thrownTypes?size > 0)><#lt> throws <@compress single_line=true> + <#list thrownTypes as exceptionType> + <@includeModel object=exceptionType/> + <#if exceptionType_has_next>, <#t> + + + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/annotation/AnnotationElement.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/annotation/AnnotationElement.ftl new file mode 100644 index 0000000000..21c1977f58 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/annotation/AnnotationElement.ftl @@ -0,0 +1,48 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.annotation.AnnotationElement" --> +<@compress single_line=true> + <#if elementName??> + ${elementName} = + + <#if (values?size > 1) > + { + + <#-- rt and lt tags below are for formatting the arrays so that there are no spaces before ',' --> + <#list values as value> + <#if boolean> + ${value?c}<#rt> + <#elseif byte> + ${value}<#rt> + <#elseif character> + '${value}'<#rt> + <#elseif class> + <@includeModel object=value raw=true/>.class<#rt> + <#elseif double> + ${value?c}<#rt> + <#elseif enum> + <@includeModel object=value/><#rt> + <#elseif float> + ${value?c}f<#rt> + <#elseif integer> + ${value?c}<#rt> + <#elseif long> + ${value?c}L<#rt> + <#elseif short> + ${value?c}<#rt> + <#elseif string> + "${value}"<#rt> + + <#if value_has_next> + , <#lt> + + + <#if (values?size > 1) > + } + + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/annotation/EnumAnnotationElementHolder.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/annotation/EnumAnnotationElementHolder.ftl new file mode 100644 index 0000000000..145b933156 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/annotation/EnumAnnotationElementHolder.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.annotation.EnumAnnotationElementHolder" --> +<@includeModel object=enumClass raw=true/>.${name}<#rt> \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/AdderWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/AdderWrapper.ftl index 190c95fa14..9160a62d9e 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/AdderWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/AdderWrapper.ftl @@ -1,29 +1,17 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.AdderWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.AdderWrapper" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.handleExceptions> - if ( ${sourceReference} != null ) { - for ( <@includeModel object=adderType.typeBound/> ${sourceLocalVarName} : ${sourceReference} ) { - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/>; + <@lib.sourceLocalVarAssignment/> + <@lib.handleSourceReferenceNullCheck> + for ( <@includeModel object=adderType.typeBound/> ${sourceLoopVarName} : <#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference} ) { + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/>; } - } + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.ftl index d1b43febb8..2ce8736f96 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ArrayCopyWrapper.ftl @@ -1,28 +1,15 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.ArrayCopyWrapper" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.handleExceptions> <@lib.sourceLocalVarAssignment/> <@lib.handleSourceReferenceNullCheck> - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>Arrays.copyOf( ${sourceLocalVarName}, ${sourceLocalVarName}.length ); + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>Arrays.copyOf( ${sourceLocalVarName}, ${sourceLocalVarName}.length ); \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.ftl index 03f8f385d9..449a273614 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/EnumConstantWrapper.ftl @@ -1,22 +1,9 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.EnumConstantWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -${ext.targetType.name}.${assignment} \ No newline at end of file +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.EnumConstantWrapper" --> +${ext.targetType.createReferenceName()}.${assignment} \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.ftl index 9a50ebbdf2..02852eec88 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ExistingInstanceSetterWrapperForCollectionsAndMaps.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.ExistingInstanceSetterWrapperForCollectionsAndMaps" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.ExistingInstanceSetterWrapperForCollectionsAndMaps" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.sourceLocalVarAssignment/> <@lib.handleExceptions> @@ -27,9 +14,13 @@ ${ext.targetBeanName}.${ext.targetReadAccessorName}.clear(); ${ext.targetBeanName}.${ext.targetReadAccessorName}.<#if ext.targetType.collectionType>addAll<#else>putAll( <@lib.handleWithAssignmentOrNullCheckVar/> ); - <#if !ext.defaultValueAssignment?? && !sourcePresenceCheckerReference?? && !includeSourceNullCheck>else {<#-- the opposite (defaultValueAssignment) case is handeld inside lib.handleLocalVarNullCheck --> - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if mapNullToDefault><@lib.initTargetObject/><#else>null; - } + <#if !ext.defaultValueAssignment?? && !sourcePresenceCheckerReference?? && includeElseBranch>else {<#-- the opposite (defaultValueAssignment) case is handeld inside lib.handleLocalVarNullCheck --> + <#if mapNullToClear> + ${ext.targetBeanName}.${ext.targetReadAccessorName}.clear(); + <#else > + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if mapNullToDefault><@lib.initTargetObject/><#else>null; + + } } else { @@ -43,6 +34,10 @@ <@lib.handleLocalVarNullCheck needs_explicit_local_var=directAssignment> ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if directAssignment><@wrapLocalVarInCollectionInitializer/><#else><@lib.handleWithAssignmentOrNullCheckVar/>; + <#if !ext.defaultValueAssignment?? && !sourcePresenceCheckerReference?? && mapNullToDefault>else { + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.initTargetObject/>; + } + <#-- wraps the local variable in a collection initializer (new collection, or EnumSet.copyOf) @@ -51,6 +46,6 @@ <#if enumSet> EnumSet.copyOf( ${nullCheckLocalVarName} ) <#else> - new <#if ext.targetType.implementationType??><@includeModel object=ext.targetType.implementationType/><#else><@includeModel object=ext.targetType/>( ${nullCheckLocalVarName} ) + <@includeModel object=newInstance/>( ${nullCheckLocalVarName} ) \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.ftl index 69f9fd6748..f47a37106e 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/GetterWrapperForCollectionsAndMaps.ftl @@ -1,32 +1,22 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.GetterWrapperForCollectionsAndMaps" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.sourceLocalVarAssignment/> if ( ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing /> != null ) { <@lib.handleExceptions> - <#if ext.existingInstanceMapping> + <#if ext.existingInstanceMapping && !ignoreMapNull> ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.clear(); <@lib.handleLocalVarNullCheck needs_explicit_local_var=false> + <#if ext.existingInstanceMapping && ignoreMapNull> + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.clear(); + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWriteAccesing />.<#if ext.targetType.collectionType>addAll<#else>putAll( <@lib.handleWithAssignmentOrNullCheckVar/> ); diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.ftl index 1cb9729d0c..4c3b6d4804 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/Java8FunctionWrapper.ftl @@ -1,24 +1,12 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.Java8FunctionWrapper" --> +<#import "../macro/CommonMacros.ftl" as lib> <#assign sourceVarName><#if assignment.sourceLocalVarName?? >${assignment.sourceLocalVarName}<#else>${assignment.sourceReference} <#if (thrownTypes?size == 0) > <#compress> @@ -30,14 +18,9 @@ <#else> <#compress> ${sourceVarName} -> { - try { + <@lib.handleExceptions> return <@_assignment/>; - } - <#list thrownTypes as exceptionType> - catch ( <@includeModel object=exceptionType/> e ) { - throw new RuntimeException( e ); - } - + } @@ -47,5 +30,6 @@ existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName + targetPropertyName=ext.targetPropertyName targetType=ext.targetType/> diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.ftl index 00bed2a9e3..163a52896a 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/LocalVarWrapper.ftl @@ -1,36 +1,19 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.LocalVarWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.LocalVarWrapper" --> +<#import "../macro/CommonMacros.ftl" as lib> <#if (thrownTypes?size == 0) > <#if !ext.isTargetDefined?? ><@includeModel object=ext.targetType/> ${ext.targetWriteAccessorName} = <@_assignment/>; <#else> <#if !ext.isTargetDefined?? ><@includeModel object=ext.targetType/> ${ext.targetWriteAccessorName}; - try { + <@lib.handleExceptions> ${ext.targetWriteAccessorName} = <@_assignment/>; - } - <#list thrownTypes as exceptionType> - catch ( <@includeModel object=exceptionType/> e ) { - throw new RuntimeException( e ); - } - + <#macro _assignment> <@includeModel object=assignment @@ -38,5 +21,6 @@ existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName + targetPropertyName=ext.targetPropertyName targetType=ext.targetType/> \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NewInstanceSetterWrapperForCollectionsAndMaps.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NewInstanceSetterWrapperForCollectionsAndMaps.ftl new file mode 100644 index 0000000000..7b9d746767 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/NewInstanceSetterWrapperForCollectionsAndMaps.ftl @@ -0,0 +1,23 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMapsWithNullCheck" --> +<#import "../macro/CommonMacros.ftl" as lib> +<@lib.sourceLocalVarAssignment/> +<@lib.handleExceptions> + <@callTargetWriteAccessor/> + +<#-- + assigns the target via the regular target write accessor (usually the setter) +--> +<#macro callTargetWriteAccessor> + <@lib.handleLocalVarNullCheck needs_explicit_local_var=directAssignment> + <#if ext.targetType.implementationType??><@includeModel object=ext.targetType.implementationType/><#else><@includeModel object=ext.targetType/> ${instanceVar} = <@includeModel object=newInstance/>(); + ${instanceVar}.<#if ext.targetType.collectionType>addAll<#else>putAll( ${nullCheckLocalVarName} ); + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite>${instanceVar}; + + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/OptionalGetWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/OptionalGetWrapper.ftl new file mode 100644 index 0000000000..7bbc089d7c --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/OptionalGetWrapper.ftl @@ -0,0 +1,15 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.OptionalGetWrapper" --> +<@compress single_line=true> +<#if optionalType.optionalBaseType.isPrimitive()> +${assignment}.getAs${optionalType.optionalBaseType.name?cap_first}() +<#else> +${assignment}.get() + + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ReturnWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ReturnWrapper.ftl new file mode 100644 index 0000000000..9917dbacf8 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/ReturnWrapper.ftl @@ -0,0 +1,18 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.ReturnWrapper" --> +return <@_assignment/>; +<#macro _assignment> + <@includeModel object=assignment + targetBeanName=ext.targetBeanName + existingInstanceMapping=ext.existingInstanceMapping + targetReadAccessorName=ext.targetReadAccessorName + targetWriteAccessorName=ext.targetWriteAccessorName + targetPropertyName=ext.targetPropertyName + targetType=ext.targetType/> + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapper.ftl index 6df7b17148..c8f18b1c7f 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapper.ftl @@ -1,28 +1,15 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapper" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.handleExceptions> <@lib.sourceLocalVarAssignment/> <@lib.handleSourceReferenceNullCheck> - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/>; + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/>; \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.ftl index 9d413fd4d5..beb6bb1f3a 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMaps.ftl @@ -1,26 +1,13 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMaps" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMaps" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.sourceLocalVarAssignment/> <@lib.handleExceptions> - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/>; + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.handleAssignment/>; \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.ftl index 102966164d..7fad115bc4 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/SetterWrapperForCollectionsAndMapsWithNullCheck.ftl @@ -1,39 +1,22 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMapsWithNullCheck" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.SetterWrapperForCollectionsAndMapsWithNullCheck" --> <#import "../macro/CommonMacros.ftl" as lib> <@lib.sourceLocalVarAssignment/> <@lib.handleExceptions> <@callTargetWriteAccessor/> - <#if !ext.defaultValueAssignment??>else {<#-- the opposite (defaultValueAssignment) case is handeld inside lib.handleLocalVarNullCheck --> - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if mapNullToDefault><@lib.initTargetObject/><#else>null; - } - <#-- assigns the target via the regular target write accessor (usually the setter) --> <#macro callTargetWriteAccessor> <@lib.handleLocalVarNullCheck needs_explicit_local_var=directAssignment> - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if directAssignment><@wrapLocalVarInCollectionInitializer/><#else><@lib.handleWithAssignmentOrNullCheckVar/>; + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if directAssignment><@wrapLocalVarInCollectionInitializer/><#else><@lib.handleWithAssignmentOrNullCheckVar/>; <#-- @@ -43,6 +26,6 @@ <#if enumSet> EnumSet.copyOf( ${nullCheckLocalVarName} ) <#else> - new <#if ext.targetType.implementationType??><@includeModel object=ext.targetType.implementationType/><#else><@includeModel object=ext.targetType/>( ${nullCheckLocalVarName} ) + <@includeModel object=newInstance/>( ${nullCheckLocalVarName} ) \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/StreamAdderWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/StreamAdderWrapper.ftl new file mode 100644 index 0000000000..6e7683e05f --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/StreamAdderWrapper.ftl @@ -0,0 +1,15 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.StreamAdderWrapper" --> +<#import "../macro/CommonMacros.ftl" as lib> +<@lib.handleExceptions> + <@lib.sourceLocalVarAssignment/> + <@lib.handleSourceReferenceNullCheck> + <#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference}.forEach( ${ext.targetBeanName}::${ext.targetWriteAccessorName} ); + + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl index 44f37eec2b..933612f579 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/assignment/UpdateWrapper.ftl @@ -1,34 +1,26 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.UpdateWrapper" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 + Copyright MapStruct Authors. - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.assignment.UpdateWrapper" --> +<#-- @ftlvariable name="ext" type="java.util.Map" --> +<#-- @ftlvariable name="ext.targetType" type="org.mapstruct.ap.internal.model.common.Type" --> <#import '../macro/CommonMacros.ftl' as lib > <@lib.handleExceptions> <#if includeSourceNullCheck> - if ( <#if sourcePresenceCheckerReference?? >${sourcePresenceCheckerReference}<#else>${sourceReference} != null ) { + <@lib.sourceLocalVarAssignment/> + if ( <@handleSourceReferenceNullCheck/> ) { <@assignToExistingTarget/> <@lib.handleAssignment/>; } + <#if setExplicitlyToDefault || setExplicitlyToNull> else { - ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if mapNullToDefault><@lib.initTargetObject/><#else>null; + ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if setExplicitlyToDefault><@lib.initTargetObject/><#else><#if mustCastForNull>(<@includeModel object=ext.targetType/>) ${ext.targetType.null}; } + <#else> <@assignToExistingTarget/> <@lib.handleAssignment/>; @@ -42,3 +34,16 @@ ${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><@lib.initTargetObject/>; } + +<#macro handleSourceReferenceNullCheck> + <@compress single_line=true> + <#if sourcePresenceCheckerReference?? > + <@includeModel object=sourcePresenceCheckerReference + targetPropertyName=ext.targetPropertyName + sourcePropertyName=ext.sourcePropertyName + targetType=ext.targetType/> + <#else> + <#if sourceLocalVarName??> ${sourceLocalVarName} <#else> ${sourceReference} != null + + + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/FinalField.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/FinalField.ftl new file mode 100644 index 0000000000..3d04bc3aec --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/FinalField.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingField" --> +private final <@includeModel object=type/> ${variableName}; \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/NegatePresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/NegatePresenceCheck.ftl new file mode 100644 index 0000000000..6951952487 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/NegatePresenceCheck.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.NegatePresenceCheck" --> +!( <@includeModel object=presenceCheck /> ) \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/NewInstanceCreation.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/NewInstanceCreation.ftl new file mode 100644 index 0000000000..9b78977245 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/NewInstanceCreation.ftl @@ -0,0 +1,11 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.NewInstanceCreation" --> +<@compress single_line=true> +new <@includeModel object=rawType/><#if generic><> + diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Parameter.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Parameter.ftl index ab33a5100a..41afd0a42e 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Parameter.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Parameter.ftl @@ -1,22 +1,9 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.Parameter" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<@includeModel object=type/> ${name} \ No newline at end of file +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.Parameter" --> +<@includeModel object=type asVarArgs=varArgs/> ${name} \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/SourceRHS.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/SourceRHS.ftl index 1e22080cff..aaf1eb8df4 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/SourceRHS.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/SourceRHS.ftl @@ -1,22 +1,9 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.SourceRHS" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -<#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference} \ No newline at end of file +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.SourceRHS" --> +<#if sourceLoopVarName?? && !ext.presenceCheck??>${sourceLoopVarName}<#elseif sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference} \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Type.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Type.ftl index 75348519c1..c039dda504 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Type.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/common/Type.ftl @@ -1,31 +1,18 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.Type" --> - <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + Copyright MapStruct Authors. - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.Type" --> <@compress single_line=true> - <#if wildCardExtendsBound> + <#if hasExtendsBound()> ? extends <@includeModel object=typeBound /> - <#elseif wildCardSuperBound> + <#elseif hasSuperBound()> ? super <@includeModel object=typeBound /> <#else> - ${referenceName}<#if (!ext.raw?? && typeParameters?size > 0) ><<#list typeParameters as typeParameter><@includeModel object=typeParameter /><#if typeParameter_has_next>, > + <#assign createReferenceName = createReferenceName() /> + ${createReferenceName?keep_before("[]")}<#if (!ext.raw?? && typeParameters?size > 0) ><<#list typeParameters as typeParameter><@includeModel object=typeParameter /><#if typeParameter_has_next>, >${createReferenceName?keep_after("[]")}<#if ext.asVarArgs!false>...<#elseif isArrayType()>[] \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl index 094102039c..0599e8c0e4 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/macro/CommonMacros.ftl @@ -1,21 +1,8 @@ <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> <#-- @@ -26,14 +13,19 @@ requires: caller to implement boolean:getIncludeSourceNullCheck() --> +<#-- @ftlvariable name="ext" type="java.util.Map" --> +<#-- @ftlvariable name="ext.targetType" type="org.mapstruct.ap.internal.model.common.Type" --> <#macro handleSourceReferenceNullCheck> <#if sourcePresenceCheckerReference??> - if ( ${sourcePresenceCheckerReference} ) { + if ( <@includeModel object=sourcePresenceCheckerReference + targetPropertyName=ext.targetPropertyName + sourcePropertyName=ext.sourcePropertyName + targetType=ext.targetType/> ) { <#nested> } <@elseDefaultAssignment/> <#elseif includeSourceNullCheck || ext.defaultValueAssignment??> - if ( <#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference} != null ) { + if ( <#if sourceLocalVarName??>${sourceLocalVarName}<#else>${sourceReference}<#if sourceType.optionalType>.isPresent()<#else> != null ) { <#nested> } <@elseDefaultAssignment/> @@ -43,12 +35,18 @@ <#-- local macro related to handleSourceReferenceNullCheck + note: the <#elseif setExplicitlyToDefault || setExplicitlyToNull> is only relevant for update mappings + the default value takes precedence --> <#macro elseDefaultAssignment> <#if ext.defaultValueAssignment?? > else { <@handeDefaultAssigment/> } + <#elseif setExplicitlyToDefault || setExplicitlyToNull> + else { + <#if ext.targetBeanName?has_content>${ext.targetBeanName}.${ext.targetWriteAccessorName}<@lib.handleWrite><#if setExplicitlyToDefault><@lib.initTargetObject/><#else><#if mustCastForNull!false>(<@includeModel object=ext.targetType/>) ${ext.targetType.null}; + } <#-- @@ -64,7 +62,10 @@ --> <#macro handleLocalVarNullCheck needs_explicit_local_var> <#if sourcePresenceCheckerReference??> - if ( ${sourcePresenceCheckerReference} ) { + if ( <@includeModel object=sourcePresenceCheckerReference + targetType=ext.targetType + sourcePropertyName=ext.sourcePropertyName + targetPropertyName=ext.targetPropertyName /> ) { <#if needs_explicit_local_var> <@includeModel object=nullCheckLocalVarType/> ${nullCheckLocalVarName} = <@lib.handleAssignment/>; <#nested> @@ -103,11 +104,16 @@ try { <#nested> } - <#list thrownTypes as exceptionType> - catch ( <@includeModel object=exceptionType/> e ) { + <@compress single_line=true>catch ( + <#list thrownTypes as exceptionType> + <#if exceptionType_index > 0> | + <@includeModel object=exceptionType/> + + e ) { + + throw new RuntimeException( e ); } - <#-- @@ -119,6 +125,7 @@ Performs a standard assignment. existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName + targetPropertyName=ext.targetPropertyName targetType=ext.targetType/> <#-- @@ -130,6 +137,7 @@ Performs a default assignment with a default value. existingInstanceMapping=ext.existingInstanceMapping targetReadAccessorName=ext.targetReadAccessorName targetWriteAccessorName=ext.targetWriteAccessorName + targetPropertyName=ext.targetPropertyName targetType=ext.targetType defaultValue=ext.defaultValue/> @@ -155,19 +163,34 @@ Performs a default assignment with a default value. <#if factoryMethod??> <@includeModel object=factoryMethod targetType=ext.targetType/> <#else> - new <@constructTargetObject/>() + <@constructTargetObject targetType=ext.targetType/> +<#-- +--> +<#macro constructArrayType targetType targetSize><@compress single_line=true> + <#assign targetTypeString><@includeModel object=targetType raw=true/> + new ${targetTypeString?keep_before("[")}[${targetSize}]${targetTypeString?keep_after("]")} + <#-- macro: constructTargetObject purpose: Either call the constructor of the target object directly or of the implementing type. + Emits the diamond operator for generic types so type-arguments are inferred from the + assignment context. --> -<#macro constructTargetObject><@compress single_line=true> - <#if ext.targetType.implementationType??> - <@includeModel object=ext.targetType.implementationType/> +<#-- @ftlvariable name="targetType" type="org.mapstruct.ap.internal.model.common.Type" --> +<#macro constructTargetObject targetType><@compress single_line=true> + <#if targetType.implementationType??> + new <@includeModel object=targetType.implementationType raw=true/><#if targetType.implementationType.typeParameters?size != 0><>() + <#elseif targetType.arrayType> + <@constructArrayType targetType=targetType targetSize=0/> + <#elseif targetType.sensibleDefault??> + ${targetType.sensibleDefault} + <#elseif targetType.optionalType> + <@includeModel object=targetType.asRawType()/>.of( <@constructTargetObject targetType=targetType.optionalBaseType/> ) <#else> - <@includeModel object=ext.targetType/> + new <@includeModel object=targetType raw=true/><#if targetType.typeParameters?size != 0><>() <#-- @@ -176,6 +199,7 @@ Performs a default assignment with a default value. purpose: assignment for source local variables. The sourceLocalVarName replaces the sourceReference in the assignmentcall. --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.common.Assignment" --> <#macro sourceLocalVarAssignment> <#if sourceLocalVarName??> <@includeModel object=sourceType/> ${sourceLocalVarName} = ${sourceReference}; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/AllPresenceChecksPresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/AllPresenceChecksPresenceCheck.ftl new file mode 100644 index 0000000000..d0c81ff2ce --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/AllPresenceChecksPresenceCheck.ftl @@ -0,0 +1,16 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.AllPresenceChecksPresenceCheck" --> +<@compress single_line=true> +<#list presenceChecks as presenceCheck> + <#if presenceCheck_index != 0> + && + + <@includeModel object=presenceCheck /> + + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/AnyPresenceChecksPresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/AnyPresenceChecksPresenceCheck.ftl new file mode 100644 index 0000000000..3df10348ad --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/AnyPresenceChecksPresenceCheck.ftl @@ -0,0 +1,16 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.AnyPresenceChecksPresenceCheck" --> +<@compress single_line=true> +<#list presenceChecks as presenceCheck> + <#if presenceCheck_index != 0> + || + + <@includeModel object=presenceCheck /> + + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/JavaExpressionPresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/JavaExpressionPresenceCheck.ftl new file mode 100644 index 0000000000..447fa375cf --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/JavaExpressionPresenceCheck.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.JavaExpressionPresenceCheck" --> +${javaExpression} \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/NullPresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/NullPresenceCheck.ftl new file mode 100644 index 0000000000..ebd9f12eca --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/NullPresenceCheck.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.NullPresenceCheck" --> +${sourceReference} <#if isNegate()>==<#else>!= null \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/OptionalPresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/OptionalPresenceCheck.ftl new file mode 100644 index 0000000000..c321ce20ec --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/OptionalPresenceCheck.ftl @@ -0,0 +1,19 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.OptionalPresenceCheck" --> +<@compress single_line=true> + <#if isNegate()> + <#if versionInformation.isSourceVersionAtLeast11()> + ${sourceReference}.isEmpty() + <#else> + !${sourceReference}.isPresent() + + <#else> + ${sourceReference}.isPresent() + + \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/SuffixPresenceCheck.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/SuffixPresenceCheck.ftl new file mode 100644 index 0000000000..8eddad3485 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/presence/SuffixPresenceCheck.ftl @@ -0,0 +1,9 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.presence.SuffixPresenceCheck" --> +<#if isNegate()>!${sourceReference}${suffix} \ No newline at end of file diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.ftl index 4220268ea3..38cf1ad852 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToXmlGregorianCalendar.ftl @@ -1,35 +1,17 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("Calendar")/> cal ) { if ( cal == null ) { return null; } - try { - <@includeModel object=findType("GregorianCalendar")/> gcal = new <@includeModel object=findType("GregorianCalendar")/>( cal.getTimeZone() ); - gcal.setTimeInMillis( cal.getTimeInMillis() ); - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( gcal ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + <@includeModel object=findType("GregorianCalendar")/> gcal = new <@includeModel object=findType("GregorianCalendar")/>( cal.getTimeZone() ); + gcal.setTimeInMillis( cal.getTimeInMillis() ); + return ${supportingField.variableName}.newXMLGregorianCalendar( gcal ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.ftl index 03815fac7c..e97a1fc69f 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/CalendarToZonedDateTime.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("ZonedDateTime")/> ${name}(<@includeModel object=findType("Calendar")/> cal) { if ( cal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.ftl index 3ed932884d..7488bc9886 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/DateToXmlGregorianCalendar.ftl @@ -1,35 +1,17 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("Date")/> date ) { if ( date == null ) { return null; } - try { - <@includeModel object=findType("GregorianCalendar")/> c = new <@includeModel object=findType("GregorianCalendar")/>(); - c.setTime( date ); - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( c ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + <@includeModel object=findType("GregorianCalendar")/> c = new <@includeModel object=findType("GregorianCalendar")/>(); + c.setTime( date ); + return ${supportingField.variableName}.newXMLGregorianCalendar( c ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.ftl index bc7da073b9..078be41af8 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JaxbElemToValue.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private T ${name}( <@includeModel object=findType("JAXBElement") raw=true/> element ) { if ( element == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.ftl index 65677e7313..aceec1f83e 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaDateTimeToXmlGregorianCalendar.ftl @@ -1,41 +1,22 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("DateTime")/> dt ) { if ( dt == null ) { return null; } - - try { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( - dt.getYear(), - dt.getMonthOfYear(), - dt.getDayOfMonth(), - dt.getHourOfDay(), - dt.getMinuteOfHour(), - dt.getSecondOfMinute(), - dt.getMillisOfSecond(), - dt.getZone().getOffset( null ) / 60000 ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + return ${supportingField.variableName}.newXMLGregorianCalendar( + dt.getYear(), + dt.getMonthOfYear(), + dt.getDayOfMonth(), + dt.getHourOfDay(), + dt.getMinuteOfHour(), + dt.getSecondOfMinute(), + dt.getMillisOfSecond(), + dt.getZone().getOffset( null ) / 60000 ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.ftl index 3e177214e8..19a9ce0a20 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateTimeToXmlGregorianCalendar.ftl @@ -1,41 +1,23 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("org.joda.time.LocalDateTime")/> dt ) { if ( dt == null ) { return null; } - try { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( - dt.getYear(), - dt.getMonthOfYear(), - dt.getDayOfMonth(), - dt.getHourOfDay(), - dt.getMinuteOfHour(), - dt.getSecondOfMinute(), - dt.getMillisOfSecond(), - <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + return ${supportingField.variableName}.newXMLGregorianCalendar( + dt.getYear(), + dt.getMonthOfYear(), + dt.getDayOfMonth(), + dt.getHourOfDay(), + dt.getMinuteOfHour(), + dt.getSecondOfMinute(), + dt.getMillisOfSecond(), + <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.ftl index 5b77e2314b..4b9b855fbd 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalDateToXmlGregorianCalendar.ftl @@ -1,37 +1,19 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("org.joda.time.LocalDate")/> dt ) { if ( dt == null ) { return null; } - try { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendarDate( - dt.getYear(), - dt.getMonthOfYear(), - dt.getDayOfMonth(), - <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + return ${supportingField.variableName}.newXMLGregorianCalendarDate( + dt.getYear(), + dt.getMonthOfYear(), + dt.getDayOfMonth(), + <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.ftl index 2add1e79c2..43a8e67a92 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/JodaLocalTimeToXmlGregorianCalendar.ftl @@ -1,38 +1,21 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("org.joda.time.LocalTime")/> dt ) { if ( dt == null ) { return null; } - try { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendarTime( - dt.getHourOfDay(), - dt.getMinuteOfHour(), - dt.getSecondOfMinute(), - dt.getMillisOfSecond(), - <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + return ${supportingField.variableName}.newXMLGregorianCalendarTime( + dt.getHourOfDay(), + dt.getMinuteOfHour(), + dt.getSecondOfMinute(), + dt.getMillisOfSecond(), + <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); + } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateTimeToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateTimeToXmlGregorianCalendar.ftl new file mode 100644 index 0000000000..fb7706b390 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateTimeToXmlGregorianCalendar.ftl @@ -0,0 +1,23 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> +private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("java.time.LocalDateTime")/> localDateTime ) { + if ( localDateTime == null ) { + return null; + } + + return ${supportingField.variableName}.newXMLGregorianCalendar( + localDateTime.getYear(), + localDateTime.getMonthValue(), + localDateTime.getDayOfMonth(), + localDateTime.getHour(), + localDateTime.getMinute(), + localDateTime.getSecond(), + localDateTime.get( ChronoField.MILLI_OF_SECOND ), + <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); +} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.ftl index e1139fed23..469bbf7508 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/LocalDateToXmlGregorianCalendar.ftl @@ -1,38 +1,19 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> -private static <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("java.time.LocalDate")/> localDate ) { +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> +private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("java.time.LocalDate")/> localDate ) { if ( localDate == null ) { return null; } - try { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendarDate( - localDate.getYear(), - localDate.getMonthValue(), - localDate.getDayOfMonth(), - <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED - ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + return ${supportingField.variableName}.newXMLGregorianCalendarDate( + localDate.getYear(), + localDate.getMonthValue(), + localDate.getDayOfMonth(), + <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/NewDatatypeFactoryConstructorFragment.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/NewDatatypeFactoryConstructorFragment.ftl new file mode 100644 index 0000000000..1dcbbe34be --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/NewDatatypeFactoryConstructorFragment.ftl @@ -0,0 +1,14 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingConstructorFragment" --> +try { + ${definingMethod.supportingField.variableName} = <@includeModel object=definingMethod.supportingField.type/>.newInstance(); +} +catch ( <@includeModel object=definingMethod.findType("DatatypeConfigurationException")/> ex ) { + throw new RuntimeException( ex ); +} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.ftl index 0e8db79d13..00c178b142 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/StringToXmlGregorianCalendar.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( String date, String dateFormat ) { if ( date == null ) { return null; @@ -29,15 +16,12 @@ private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( String <@includeModel object=findType("DateFormat")/> df = new <@includeModel object=findType("SimpleDateFormat")/>( dateFormat ); <@includeModel object=findType("GregorianCalendar")/> c = new <@includeModel object=findType("GregorianCalendar")/>(); c.setTime( df.parse( date ) ); - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( c ); + return ${supportingField.variableName}.newXMLGregorianCalendar( c ); } else { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( date ); + return ${supportingField.variableName}.newXMLGregorianCalendar( date ); } } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } catch ( <@includeModel object=findType("ParseException")/> ex ) { throw new RuntimeException( ex ); } diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.ftl index 2021d776df..cfc4ed2adf 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToCalendar.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("Calendar")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.ftl index 88fe71b486..f4ebaab9ca 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToDate.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private static <@includeModel object=findType("java.util.Date")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.ftl index 1e4799dc89..15fa82bc51 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaDateTime.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private static <@includeModel object=findType("DateTime")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.ftl index e51d87a13e..3067f5dd65 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDate.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private static <@includeModel object=findType("org.joda.time.LocalDate")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.ftl index edcf3e3a33..6ace975194 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalDateTime.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private static <@includeModel object=findType("org.joda.time.LocalDateTime")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.ftl index 1396324452..392401b3f9 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToJodaLocalTime.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private static <@includeModel object=findType("org.joda.time.LocalTime")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.ftl index fc69fdd5b3..81141a41fb 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDate.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private static <@includeModel object=findType("java.time.LocalDate")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDateTime.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDateTime.ftl new file mode 100644 index 0000000000..6eef5513a4 --- /dev/null +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToLocalDateTime.ftl @@ -0,0 +1,53 @@ +<#-- + + Copyright MapStruct Authors. + + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + +--> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> +private static <@includeModel object=findType("java.time.LocalDateTime")/> ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal ) { + if ( xcal == null ) { + return null; + } + + if ( xcal.getYear() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED + && xcal.getMonth() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED + && xcal.getDay() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED + && xcal.getHour() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED + && xcal.getMinute() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED + ) { + if ( xcal.getSecond() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED + && xcal.getMillisecond() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ) { + return <@includeModel object=findType("java.time.LocalDateTime")/>.of( + xcal.getYear(), + xcal.getMonth(), + xcal.getDay(), + xcal.getHour(), + xcal.getMinute(), + xcal.getSecond(), + Duration.ofMillis( xcal.getMillisecond() ).getNano() + ); + } + else if ( xcal.getSecond() != <@includeModel object=findType("DatatypeConstants")/>.FIELD_UNDEFINED ) { + return <@includeModel object=findType("java.time.LocalDateTime")/>.of( + xcal.getYear(), + xcal.getMonth(), + xcal.getDay(), + xcal.getHour(), + xcal.getMinute(), + xcal.getSecond() + ); + } + else { + return <@includeModel object=findType("java.time.LocalDateTime")/>.of( + xcal.getYear(), + xcal.getMonth(), + xcal.getDay(), + xcal.getHour(), + xcal.getMinute() + ); + } + } + return null; +} diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.ftl index 5a705aa74a..99c0237eec 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/XmlGregorianCalendarToString.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private String ${name}( <@includeModel object=findType("XMLGregorianCalendar")/> xcal, String dateFormat ) { if ( xcal == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.ftl index 47a951a29c..6a96241e34 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToCalendar.ftl @@ -1,24 +1,11 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("Calendar")/> ${name}(<@includeModel object=findType("ZonedDateTime")/> dateTime) { if ( dateTime == null ) { return null; diff --git a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.ftl b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.ftl index 116d5d3525..b187daa957 100644 --- a/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.ftl +++ b/processor/src/main/resources/org/mapstruct/ap/internal/model/source/builtin/ZonedDateTimeToXmlGregorianCalendar.ftl @@ -1,33 +1,15 @@ -<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.VirtualMappingMethod" --> <#-- - Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - and/or other contributors as indicated by the @authors tag. See the - copyright.txt file in the distribution for a full listing of all - contributors. + Copyright MapStruct Authors. - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. + Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 --> +<#-- @ftlvariable name="" type="org.mapstruct.ap.internal.model.SupportingMappingMethod" --> private <@includeModel object=findType("XMLGregorianCalendar")/> ${name}( <@includeModel object=findType("ZonedDateTime")/> zdt ) { if ( zdt == null ) { return null; } - try { - return <@includeModel object=findType("DatatypeFactory")/>.newInstance().newXMLGregorianCalendar( <@includeModel object=findType("GregorianCalendar")/>.from( zdt ) ); - } - catch ( <@includeModel object=findType("DatatypeConfigurationException")/> ex ) { - throw new RuntimeException( ex ); - } + return ${supportingField.variableName}.newXMLGregorianCalendar( <@includeModel object=findType("GregorianCalendar")/>.from( zdt ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactoryTest.java index 47ded40dab..ba890f0e87 100755 --- a/processor/src/test/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/internal/model/common/DateFormatValidatorFactoryTest.java @@ -1,38 +1,28 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; -import static org.assertj.core.api.Assertions.assertThat; - import java.lang.annotation.Annotation; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZonedDateTime; +import java.util.HashMap; import java.util.List; - import javax.lang.model.element.AnnotationMirror; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVisitor; -import org.junit.Test; -import org.mapstruct.ap.internal.util.JavaTimeConstants; +import org.junit.jupiter.api.Test; import org.mapstruct.ap.internal.util.JodaTimeConstants; import org.mapstruct.ap.testutil.IssueKey; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests for {@link org.mapstruct.ap.internal.model.common.DateFormatValidatorFactory}. * @@ -126,25 +116,25 @@ public void testJavaTimeValidator() { Type targetType = typeWithFQN( JAVA_LANG_STRING ); - Type sourceType = typeWithFQN( JavaTimeConstants.ZONED_DATE_TIME_FQN ); + Type sourceType = typeWithFQN( ZonedDateTime.class.getCanonicalName() ); assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( targetType, sourceType ); assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( targetType, sourceType ); - sourceType = typeWithFQN( JavaTimeConstants.LOCAL_DATE_FQN ); + sourceType = typeWithFQN( LocalDate.class.getCanonicalName() ); assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( targetType, sourceType ); assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( targetType, sourceType ); - sourceType = typeWithFQN( JavaTimeConstants.LOCAL_DATE_TIME_FQN ); + sourceType = typeWithFQN( LocalDateTime.class.getCanonicalName() ); assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( targetType, sourceType ); assertValidDateFormat( sourceType, targetType ); assertValidDateFormat( targetType, sourceType ); - sourceType = typeWithFQN( JavaTimeConstants.LOCAL_TIME_FQN ); + sourceType = typeWithFQN( LocalTime.class.getCanonicalName() ); assertInvalidDateFormat( sourceType, targetType ); assertInvalidDateFormat( targetType, sourceType ); assertValidDateFormat( sourceType, targetType ); @@ -176,7 +166,6 @@ private Type typeWithFQN(String fullQualifiedName) { null, null, null, - null, fullQualifiedName, false, false, @@ -184,8 +173,11 @@ private Type typeWithFQN(String fullQualifiedName) { false, false, false, + new HashMap<>( ), + new HashMap<>( ), false, - false ); + false, false + ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/internal/model/common/DefaultConversionContextTest.java b/processor/src/test/java/org/mapstruct/ap/internal/model/common/DefaultConversionContextTest.java index 742e4391d5..3d12de6e0b 100755 --- a/processor/src/test/java/org/mapstruct/ap/internal/model/common/DefaultConversionContextTest.java +++ b/processor/src/test/java/org/mapstruct/ap/internal/model/common/DefaultConversionContextTest.java @@ -1,28 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.common; -import static org.assertj.core.api.Assertions.assertThat; - import java.lang.annotation.Annotation; +import java.time.ZonedDateTime; +import java.util.HashMap; import java.util.List; - import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.AnnotationValue; import javax.lang.model.element.Element; @@ -31,12 +17,13 @@ import javax.lang.model.type.TypeVisitor; import javax.tools.Diagnostic; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mapstruct.ap.internal.util.FormattingMessager; -import org.mapstruct.ap.internal.util.JavaTimeConstants; import org.mapstruct.ap.internal.util.Message; import org.mapstruct.ap.testutil.IssueKey; +import static org.assertj.core.api.Assertions.assertThat; + /** * Testing DefaultConversionContext for dateFormat * @@ -75,28 +62,28 @@ public R accept(TypeVisitor v, P p) { @Test public void testInvalidDateFormatValidation() { - Type type = typeWithFQN( JavaTimeConstants.ZONED_DATE_TIME_FQN ); + Type type = typeWithFQN( ZonedDateTime.class.getCanonicalName() ); StatefulMessagerMock statefulMessagerMock = new StatefulMessagerMock(); new DefaultConversionContext( null, statefulMessagerMock, type, type, - new FormattingParameters( "qwertz", null, null, null, null ) + new FormattingParameters( "qwertz", null, null, null, null, null ) ); assertThat( statefulMessagerMock.getLastKindPrinted() ).isEqualTo( Diagnostic.Kind.ERROR ); } @Test public void testNullDateFormatValidation() { - Type type = typeWithFQN( JavaTimeConstants.ZONED_DATE_TIME_FQN ); + Type type = typeWithFQN( ZonedDateTime.class.getCanonicalName() ); StatefulMessagerMock statefulMessagerMock = new StatefulMessagerMock(); new DefaultConversionContext( null, statefulMessagerMock, type, type, - new FormattingParameters( null, null, null, null, null ) + new FormattingParameters( null, null, null, null, null, null ) ); assertThat( statefulMessagerMock.getLastKindPrinted() ).isNull(); } @@ -109,7 +96,7 @@ public void testUnsupportedType() { statefulMessagerMock, type, type, - new FormattingParameters( "qwertz", null, null, null, null ) + new FormattingParameters( "qwertz", null, null, null, null, null ) ); assertThat( statefulMessagerMock.getLastKindPrinted() ).isNull(); } @@ -127,7 +114,6 @@ private Type typeWithFQN(String fullQualifiedName) { null, null, null, - null, fullQualifiedName, false, false, @@ -135,8 +121,11 @@ private Type typeWithFQN(String fullQualifiedName) { false, false, false, + new HashMap<>( ), + new HashMap<>( ), false, - false ); + false, false + ); } private static class StatefulMessagerMock implements FormattingMessager { @@ -163,9 +152,18 @@ public void printMessage(Element e, AnnotationMirror a, AnnotationValue v, Messa lastKindPrinted = msg.getDiagnosticKind(); } + @Override + public void note(int level, Message msg, Object... args) { + throw new UnsupportedOperationException( "Should not be called" ); + } + public Diagnostic.Kind getLastKindPrinted() { return lastKindPrinted; } + @Override + public boolean isErroneous() { + return false; + } } } diff --git a/processor/src/test/java/org/mapstruct/ap/internal/model/common/TypeFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/internal/model/common/TypeFactoryTest.java deleted file mode 100644 index 213bcb4f93..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/internal/model/common/TypeFactoryTest.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.internal.model.common; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; - -public class TypeFactoryTest { - - @Test - public void shouldReturnNullIfNoClassNameIsProvided() { - String result = TypeFactory.trimSimpleClassName( null ); - - assertThat( result ).isNull(); - } - - @Test - public void shouldNotModifyClassNameIfNotAnArray() { - String className = "SimpleClass"; - - String result = TypeFactory.trimSimpleClassName( className ); - - assertThat( result ).isEqualTo( className ); - } - - @Test - public void shouldTrimOneDimensionalArray() { - String result = TypeFactory.trimSimpleClassName( "SimpleClass[]" ); - - assertThat( result ).isEqualTo( "SimpleClass" ); - } - - @Test - public void shouldTrimTwoDimensionalArray() { - String result = TypeFactory.trimSimpleClassName( "SimpleClass[][]" ); - - assertThat( result ).isEqualTo( "SimpleClass" ); - } - - @Test - public void shouldTrimMultiDimensionalArray() { - String result = TypeFactory.trimSimpleClassName( "SimpleClass[][][][][]" ); - - assertThat( result ).isEqualTo( "SimpleClass" ); - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/internal/model/source/SelectionParametersTest.java b/processor/src/test/java/org/mapstruct/ap/internal/model/source/SelectionParametersTest.java index b5ff2a7f44..4c6e78e0c1 100644 --- a/processor/src/test/java/org/mapstruct/ap/internal/model/source/SelectionParametersTest.java +++ b/processor/src/test/java/org/mapstruct/ap/internal/model/source/SelectionParametersTest.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.model.source; @@ -36,9 +23,9 @@ import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVisitor; import javax.lang.model.type.WildcardType; -import javax.lang.model.util.Types; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.mapstruct.ap.internal.util.TypeUtils; import static org.assertj.core.api.Assertions.assertThat; @@ -86,7 +73,12 @@ public String toString() { } } - private final Types typeUtils = new Types() { + private final TypeUtils typeUtils = new TypeUtils() { + @Override + public boolean isSubtypeErased(TypeMirror t1, TypeMirror t2) { + throw new UnsupportedOperationException( "isSubTypeErased is not supported" ); + } + @Override public Element asElement(TypeMirror t) { throw new UnsupportedOperationException( "asElement is not supported" ); @@ -187,7 +179,7 @@ public TypeMirror asMemberOf(DeclaredType containing, Element element) { public void testGetters() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); @@ -239,7 +231,7 @@ public void testHashCodeWithNullResultType() { public void testEqualsSameInstance() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); @@ -251,7 +243,7 @@ public void testEqualsSameInstance() { public void testEqualsWitNull() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); @@ -263,7 +255,7 @@ public void testEqualsWitNull() { public void testEqualsQualifiersOneNull() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); @@ -277,12 +269,12 @@ public void testEqualsQualifiersOneNull() { public void testEqualsQualifiersInDifferentOrder() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); - List qualifiers2 = new ArrayList(); + List qualifiers2 = new ArrayList<>(); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); SelectionParameters params2 = new SelectionParameters( qualifiers2, qualifyingNames, resultType, typeUtils ); @@ -295,12 +287,12 @@ public void testEqualsQualifiersInDifferentOrder() { public void testEqualsQualifyingNamesOneNull() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); - List qualifiers2 = new ArrayList(); + List qualifiers2 = new ArrayList<>(); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params2 = new SelectionParameters( qualifiers2, null, resultType, typeUtils ); @@ -313,13 +305,13 @@ public void testEqualsQualifyingNamesOneNull() { public void testEqualsQualifyingNamesInDifferentOrder() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); List qualifyingNames2 = Arrays.asList( "german", "language" ); - List qualifiers2 = new ArrayList(); + List qualifiers2 = new ArrayList<>(); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); SelectionParameters params2 = new SelectionParameters( qualifiers2, qualifyingNames2, resultType, typeUtils ); @@ -332,13 +324,13 @@ public void testEqualsQualifyingNamesInDifferentOrder() { public void testEqualsResultTypeOneNull() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); List qualifyingNames2 = Arrays.asList( "language", "german" ); - List qualifiers2 = new ArrayList(); + List qualifiers2 = new ArrayList<>(); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params2 = new SelectionParameters( qualifiers2, qualifyingNames2, null, typeUtils ); @@ -351,14 +343,14 @@ public void testEqualsResultTypeOneNull() { public void testAllEqual() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); List qualifyingNames2 = Arrays.asList( "language", "german" ); TypeMirror resultType2 = new TestTypeMirror( "resultType" ); - List qualifiers2 = new ArrayList(); + List qualifiers2 = new ArrayList<>(); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params2 = new SelectionParameters( qualifiers2, qualifyingNames2, resultType2, typeUtils ); @@ -371,14 +363,14 @@ public void testAllEqual() { public void testDifferentResultTypes() { List qualifyingNames = Arrays.asList( "language", "german" ); TypeMirror resultType = new TestTypeMirror( "resultType" ); - List qualifiers = new ArrayList(); + List qualifiers = new ArrayList<>(); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params = new SelectionParameters( qualifiers, qualifyingNames, resultType, typeUtils ); List qualifyingNames2 = Arrays.asList( "language", "german" ); TypeMirror resultType2 = new TestTypeMirror( "otherResultType" ); - List qualifiers2 = new ArrayList(); + List qualifiers2 = new ArrayList<>(); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeType" ) ); qualifiers2.add( new TestTypeMirror( "org.mapstruct.test.SomeOtherType" ) ); SelectionParameters params2 = new SelectionParameters( qualifiers2, qualifyingNames2, resultType2, typeUtils ); diff --git a/processor/src/test/java/org/mapstruct/ap/internal/util/NativeTypesTest.java b/processor/src/test/java/org/mapstruct/ap/internal/util/NativeTypesTest.java index 2555209259..f3ba8d3a8c 100644 --- a/processor/src/test/java/org/mapstruct/ap/internal/util/NativeTypesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/internal/util/NativeTypesTest.java @@ -1,30 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.math.BigDecimal; import java.math.BigInteger; -import org.junit.Test; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Ciaran Liedeman @@ -32,7 +20,7 @@ public class NativeTypesTest { @Test - public void testIsNumber() throws Exception { + public void testIsNumber() { assertFalse( NativeTypes.isNumber( null ) ); assertFalse( NativeTypes.isNumber( Object.class ) ); assertFalse( NativeTypes.isNumber( String.class ) ); @@ -134,7 +122,7 @@ public void testIntegerLiteralFromJLS() { .isNotNull(); // most negative int: dec / octal / int / binary - // NOTE parseInt should be changed to parseUnsignedInt in Java, than the - sign can disssapear (java8) + // NOTE parseInt should be changed to parseUnsignedInt in Java, than the - sign can dissapear (java8) // and the function will be true to what the compiler shows. assertThat( getLiteral( int.class.getCanonicalName(), "-2147483648" ) ).isNotNull(); assertThat( getLiteral( int.class.getCanonicalName(), "0x8000_0000" ) ).isNotNull(); @@ -189,7 +177,7 @@ public void testIntegerLiteralFromJLS() { * The following example shows other ways you can use the underscore in numeric literals: */ @Test - public void testFloatingPoingLiteralFromJLS() { + public void testFloatingPointLiteralFromJLS() { // The largest positive finite literal of type float is 3.4028235e38f. assertThat( getLiteral( float.class.getCanonicalName(), "3.4028235e38f" ) ).isNotNull(); diff --git a/processor/src/test/java/org/mapstruct/ap/internal/util/StringsTest.java b/processor/src/test/java/org/mapstruct/ap/internal/util/StringsTest.java index 3959d6ac17..20c7a766a6 100644 --- a/processor/src/test/java/org/mapstruct/ap/internal/util/StringsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/internal/util/StringsTest.java @@ -1,53 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.internal.util; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; import java.util.Arrays; -import java.util.Locale; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.Test; +import org.junitpioneer.jupiter.DefaultLocale; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ public class StringsTest { - private static final Locale TURKEY_LOCALE = getTurkeyLocale(); - private Locale defaultLocale; - - @Before - public void before() { - defaultLocale = Locale.getDefault(); - } - - @After - public void after() { - Locale.setDefault( defaultLocale ); - } - @Test - public void testCapitalize() throws Exception { + public void testCapitalize() { assertThat( Strings.capitalize( null ) ).isNull(); assertThat( Strings.capitalize( "c" ) ).isEqualTo( "C" ); assertThat( Strings.capitalize( "capitalize" ) ).isEqualTo( "Capitalize" ); @@ -56,7 +28,7 @@ public void testCapitalize() throws Exception { } @Test - public void testDecapitalize() throws Exception { + public void testDecapitalize() { assertThat( Strings.decapitalize( null ) ).isNull(); assertThat( Strings.decapitalize( "c" ) ).isEqualTo( "c" ); assertThat( Strings.decapitalize( "capitalize" ) ).isEqualTo( "capitalize" ); @@ -65,14 +37,14 @@ public void testDecapitalize() throws Exception { } @Test - public void testJoin() throws Exception { + public void testJoin() { assertThat( Strings.join( new ArrayList(), "-" ) ).isEqualTo( "" ); assertThat( Strings.join( Arrays.asList( "Hello", "World" ), "-" ) ).isEqualTo( "Hello-World" ); assertThat( Strings.join( Arrays.asList( "Hello" ), "-" ) ).isEqualTo( "Hello" ); } @Test - public void testJoinAndCamelize() throws Exception { + public void testJoinAndCamelize() { assertThat( Strings.joinAndCamelize( new ArrayList() ) ).isEqualTo( "" ); assertThat( Strings.joinAndCamelize( Arrays.asList( "Hello", "World" ) ) ).isEqualTo( "HelloWorld" ); assertThat( Strings.joinAndCamelize( Arrays.asList( "Hello", "world" ) ) ).isEqualTo( "HelloWorld" ); @@ -80,7 +52,7 @@ public void testJoinAndCamelize() throws Exception { } @Test - public void testIsEmpty() throws Exception { + public void testIsEmpty() { assertThat( Strings.isEmpty( null ) ).isTrue(); assertThat( Strings.isEmpty( "" ) ).isTrue(); assertThat( Strings.isEmpty( " " ) ).isFalse(); @@ -88,39 +60,63 @@ public void testIsEmpty() throws Exception { } @Test - public void testGetSaveVariableNameWithArrayExistingVariables() throws Exception { - assertThat( Strings.getSaveVariableName( "int[]" ) ).isEqualTo( "intArray" ); - assertThat( Strings.getSaveVariableName( "Extends" ) ).isEqualTo( "extends1" ); - assertThat( Strings.getSaveVariableName( "class" ) ).isEqualTo( "class1" ); - assertThat( Strings.getSaveVariableName( "Class" ) ).isEqualTo( "class1" ); - assertThat( Strings.getSaveVariableName( "Case" ) ).isEqualTo( "case1" ); - assertThat( Strings.getSaveVariableName( "Synchronized" ) ).isEqualTo( "synchronized1" ); - assertThat( Strings.getSaveVariableName( "prop", "prop", "prop_" ) ).isEqualTo( "prop1" ); + public void testGetSaveVariableNameWithArrayExistingVariables() { + assertThat( Strings.getSafeVariableName( "int[]" ) ).isEqualTo( "intArray" ); + assertThat( Strings.getSafeVariableName( "Extends" ) ).isEqualTo( "extends1" ); + assertThat( Strings.getSafeVariableName( "class" ) ).isEqualTo( "class1" ); + assertThat( Strings.getSafeVariableName( "Class" ) ).isEqualTo( "class1" ); + assertThat( Strings.getSafeVariableName( "Case" ) ).isEqualTo( "case1" ); + assertThat( Strings.getSafeVariableName( "Synchronized" ) ).isEqualTo( "synchronized1" ); + assertThat( Strings.getSafeVariableName( "prop", "prop", "prop_" ) ).isEqualTo( "prop1" ); + assertThat( Strings.getSafeVariableName( "_Test" ) ).isEqualTo( "test" ); + assertThat( Strings.getSafeVariableName( "__Test" ) ).isEqualTo( "test" ); + assertThat( Strings.getSafeVariableName( "_0Test" ) ).isEqualTo( "test" ); + assertThat( Strings.getSafeVariableName( "_0123Test" ) ).isEqualTo( "test" ); + assertThat( Strings.getSafeVariableName( "bad/test" ) ).isEqualTo( "bad_test" ); } @Test - public void testGetSaveVariableNameVariablesEndingOnNumberVariables() throws Exception { - assertThat( Strings.getSaveVariableName( "prop1", "prop1" ) ).isEqualTo( "prop1_1" ); - assertThat( Strings.getSaveVariableName( "prop1", "prop1", "prop1_1" ) ).isEqualTo( "prop1_2" ); + public void testGetSaveVariableNameVariablesEndingOnNumberVariables() { + assertThat( Strings.getSafeVariableName( "prop1", "prop1" ) ).isEqualTo( "prop1_1" ); + assertThat( Strings.getSafeVariableName( "prop1", "prop1", "prop1_1" ) ).isEqualTo( "prop1_2" ); } @Test - public void testGetSaveVariableNameWithCollection() throws Exception { - assertThat( Strings.getSaveVariableName( "int[]", new ArrayList() ) ).isEqualTo( "intArray" ); - assertThat( Strings.getSaveVariableName( "Extends", new ArrayList() ) ).isEqualTo( "extends1" ); - assertThat( Strings.getSaveVariableName( "prop", Arrays.asList( "prop", "prop1" ) ) ).isEqualTo( "prop2" ); - assertThat( Strings.getSaveVariableName( "prop.font", Arrays.asList( "propFont", "propFont_" ) ) ) + public void testGetSaveVariableNameWithCollection() { + assertThat( Strings.getSafeVariableName( "int[]", new ArrayList<>() ) ).isEqualTo( "intArray" ); + assertThat( Strings.getSafeVariableName( "Extends", new ArrayList<>() ) ).isEqualTo( "extends1" ); + assertThat( Strings.getSafeVariableName( "prop", Arrays.asList( "prop", "prop1" ) ) ).isEqualTo( "prop2" ); + assertThat( Strings.getSafeVariableName( "prop.font", Arrays.asList( "propFont", "propFont_" ) ) ) .isEqualTo( "propFont1" ); + assertThat( Strings.getSafeVariableName( "_Test", new ArrayList<>() ) ).isEqualTo( "test" ); + assertThat( Strings.getSafeVariableName( "__Test", Arrays.asList( "test" ) ) ).isEqualTo( "test1" ); + assertThat( Strings.getSafeVariableName( "___", new ArrayList<>() ) ).isEqualTo( "___" ); + assertThat( Strings.getSafeVariableName( "_0Test", new ArrayList<>() ) ).isEqualTo( "test" ); + assertThat( Strings.getSafeVariableName( "__0Test", Arrays.asList( "test" ) ) ).isEqualTo( "test1" ); + assertThat( Strings.getSafeVariableName( "___0", new ArrayList<>() ) ).isEqualTo( "___0" ); + assertThat( Strings.getSafeVariableName( "__0123456789Test", Arrays.asList( "test" ) ) ).isEqualTo( "test1" ); + assertThat( Strings.getSafeVariableName( "bad/test", Arrays.asList( "bad_test" ) ) ).isEqualTo( "bad_test1" ); } @Test - public void testSanitizeIdentifierName() throws Exception { + public void testSanitizeIdentifierName() { assertThat( Strings.sanitizeIdentifierName( "test" ) ).isEqualTo( "test" ); assertThat( Strings.sanitizeIdentifierName( "int[]" ) ).isEqualTo( "intArray" ); + assertThat( Strings.sanitizeIdentifierName( "_Test" ) ).isEqualTo( "Test" ); + assertThat( Strings.sanitizeIdentifierName( "_int[]" ) ).isEqualTo( "intArray" ); + assertThat( Strings.sanitizeIdentifierName( "__int[]" ) ).isEqualTo( "intArray" ); + assertThat( Strings.sanitizeIdentifierName( "test_" ) ).isEqualTo( "test_" ); + assertThat( Strings.sanitizeIdentifierName( "___" ) ).isEqualTo( "___" ); + assertThat( Strings.sanitizeIdentifierName( "_0Test" ) ).isEqualTo( "Test" ); + assertThat( Strings.sanitizeIdentifierName( "_0123456789Test" ) ).isEqualTo( "Test" ); + assertThat( Strings.sanitizeIdentifierName( "_0int[]" ) ).isEqualTo( "intArray" ); + assertThat( Strings.sanitizeIdentifierName( "__0int[]" ) ).isEqualTo( "intArray" ); + assertThat( Strings.sanitizeIdentifierName( "___0" ) ).isEqualTo( "___0" ); + assertThat( Strings.sanitizeIdentifierName( "bad/test" ) ).isEqualTo( "bad_test" ); } @Test - public void findMostSimilarWord() throws Exception { + public void findMostSimilarWord() { String mostSimilarWord = Strings.getMostSimilarWord( "fulName", Arrays.asList( "fullAge", "fullName", "address", "status" ) @@ -129,40 +125,31 @@ public void findMostSimilarWord() throws Exception { } @Test + @DefaultLocale("en") public void capitalizeEnglish() { - Locale.setDefault( Locale.ENGLISH ); String international = Strings.capitalize( "international" ); assertThat( international ).isEqualTo( "International" ); } @Test + @DefaultLocale("en") public void decapitalizeEnglish() { - Locale.setDefault( Locale.ENGLISH ); String international = Strings.decapitalize( "International" ); assertThat( international ).isEqualTo( "international" ); } @Test + @DefaultLocale("tr") public void capitalizeTurkish() { - Locale.setDefault( TURKEY_LOCALE ); String international = Strings.capitalize( "international" ); assertThat( international ).isEqualTo( "International" ); } @Test + @DefaultLocale("tr") public void decapitalizeTurkish() { - Locale.setDefault( TURKEY_LOCALE ); String international = Strings.decapitalize( "International" ); assertThat( international ).isEqualTo( "international" ); } - private static Locale getTurkeyLocale() { - Locale turkeyLocale = Locale.forLanguageTag( "tr" ); - - if ( turkeyLocale == null ) { - throw new IllegalStateException( "Can't find Turkey locale." ); - } - - return turkeyLocale; - } } diff --git a/processor/src/test/java/org/mapstruct/ap/spi/util/IntrospectorUtilsTest.java b/processor/src/test/java/org/mapstruct/ap/spi/util/IntrospectorUtilsTest.java new file mode 100644 index 0000000000..84469f3f64 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/spi/util/IntrospectorUtilsTest.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.spi.util; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Saheb Preet Singh + */ +public class IntrospectorUtilsTest { + + @Test + public void testDecapitalize() { + assertThat( IntrospectorUtils.decapitalize( null ) ).isNull(); + assertThat( IntrospectorUtils.decapitalize( "" ) ).isEqualTo( "" ); + assertThat( IntrospectorUtils.decapitalize( "URL" ) ).isEqualTo( "URL" ); + assertThat( IntrospectorUtils.decapitalize( "FooBar" ) ).isEqualTo( "fooBar" ); + assertThat( IntrospectorUtils.decapitalize( "PArtialCapitalized" ) ).isEqualTo( "PArtialCapitalized" ); + assertThat( IntrospectorUtils.decapitalize( "notCapitalized" ) ).isEqualTo( "notCapitalized" ); + assertThat( IntrospectorUtils.decapitalize( "a" ) ).isEqualTo( "a" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/NoProperties.java b/processor/src/test/java/org/mapstruct/ap/test/NoProperties.java index 4a2c74081e..20efe22568 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/NoProperties.java +++ b/processor/src/test/java/org/mapstruct/ap/test/NoProperties.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test; diff --git a/processor/src/test/java/org/mapstruct/ap/test/WithProperties.java b/processor/src/test/java/org/mapstruct/ap/test/WithProperties.java index 5d879dbdcc..2a13360e24 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/WithProperties.java +++ b/processor/src/test/java/org/mapstruct/ap/test/WithProperties.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractBaseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractBaseMapper.java index 955fb2d93f..87eb21b8ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractBaseMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractBaseMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractClassTest.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractClassTest.java index 77441c2082..4e931b487b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractClassTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractClassTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for the generation of implementation of abstract base classes. @@ -41,12 +26,12 @@ Identifiable.class, HasId.class, AlsoHasId.class, - Measurable.class + Measurable.class, + Holder.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class AbstractClassTest { - @Test + @ProcessorTest @IssueKey("64") public void shouldCreateImplementationOfAbstractMethod() { Source source = new Source(); @@ -54,7 +39,7 @@ public void shouldCreateImplementationOfAbstractMethod() { assertResult( SourceTargetMapper.INSTANCE.sourceToTarget( source ) ); } - @Test + @ProcessorTest @IssueKey("165") public void shouldCreateImplementationOfMethodFromSuper() { Source source = new Source(); @@ -62,7 +47,7 @@ public void shouldCreateImplementationOfMethodFromSuper() { assertResult( SourceTargetMapper.INSTANCE.sourceToTargetFromBaseMapper( source ) ); } - @Test + @ProcessorTest @IssueKey("165") public void shouldCreateImplementationOfMethodFromInterface() { Source source = new Source(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractDto.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractDto.java index b674d184d9..46af734731 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractReferencedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractReferencedMapper.java index 3b50357486..8fd8ab0ef4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractReferencedMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AbstractReferencedMapper.java @@ -1,40 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; -import javax.xml.ws.Holder; - /** * @author Andreas Gudian */ public abstract class AbstractReferencedMapper implements ReferencedMapperInterface { + @Override public int holderToInt(Holder holder) { return 41; } public boolean objectToBoolean(Object obj) { - if ( obj instanceof String ) { - return true; - } - - return false; + return obj instanceof String; } @Override diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AlsoHasId.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AlsoHasId.java index cc0c58c054..1cb76008c7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AlsoHasId.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/AlsoHasId.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/BaseMapperInterface.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/BaseMapperInterface.java index 17881cfb53..0c9e1ef445 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/BaseMapperInterface.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/BaseMapperInterface.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/HasId.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/HasId.java index a29ad24337..d611b229ee 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/HasId.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/HasId.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Holder.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Holder.java new file mode 100644 index 0000000000..e05e062464 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Holder.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.abstractclass; + +/** + * @author Gunnar Morling + */ +public class Holder { + + public Holder(String string) { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Identifiable.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Identifiable.java index be8c65e356..57561049de 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Identifiable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Identifiable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Measurable.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Measurable.java index 1d0775f00b..b8351b036f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Measurable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Measurable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapper.java index ed69807454..c2a01d3f8e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapper.java @@ -1,29 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; -import javax.xml.ws.Holder; - /** * @author Andreas Gudian */ public class ReferencedMapper extends AbstractReferencedMapper { + @Override public int holderToInt(Holder holder) { return 42; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapperInterface.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapperInterface.java index 089932d170..5d4e3d8661 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapperInterface.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/ReferencedMapperInterface.java @@ -1,28 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; -import javax.xml.ws.Holder; - /** * @author Andreas Gudian */ public interface ReferencedMapperInterface { + int holderToInt(Holder holder); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Source.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Source.java index 655704f78d..703bc7daf1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Source.java @@ -1,27 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; import java.util.Calendar; -import javax.xml.ws.Holder; - public class Source extends AbstractDto implements HasId, AlsoHasId { //CHECKSTYLE:OFF @@ -30,7 +15,7 @@ public class Source extends AbstractDto implements HasId, AlsoHasId { private final int size; private final Calendar birthday; private final String notAttractingEqualsMethod = "no way"; - private final Holder manuallyConverted = new Holder( "What is the answer?" ); + private final Holder manuallyConverted = new Holder<>( "What is the answer?" ); public Source() { publicSize = 191; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/SourceTargetMapper.java index 547f34566b..0f8227b3f0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Target.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Target.java index 6c91111a08..fef4406ebc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractAnimal.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractAnimal.java index 7d3d2fa12a..6a82bcc727 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractAnimal.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractAnimal.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractHuman.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractHuman.java index a3965992bd..2e38329f1a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractHuman.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AbstractHuman.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AnimalKey.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AnimalKey.java index 9fe80557e8..ee95bb8884 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AnimalKey.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/AnimalKey.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Child.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Child.java index 0ce601b65f..f1f9034def 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Child.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Child.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Elephant.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Elephant.java index 60de8084f9..9d0b37723a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Elephant.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Elephant.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericIdentifiable.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericIdentifiable.java index a7e73bb716..a4107ce86e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericIdentifiable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericIdentifiable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyMapper.java index c7ede0e588..d002b1304b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyTest.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyTest.java index 2d404d4d93..fa483c9037 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/GenericsHierarchyTest.java @@ -1,36 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.runner.Compiler; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian * */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("644,687,688") @WithClasses({ AbstractAnimal.class, @@ -46,7 +31,11 @@ }) public class GenericsHierarchyTest { - @Test + // Running only with the JDK compiler due to a bug in the Eclipse compiler + // (https://bugs.eclipse.org/bugs/show_bug.cgi?id=540101) + // See https://github.com/mapstruct/mapstruct/issues/1553 and https://github.com/mapstruct/mapstruct/pull/1587 + // for more information + @ProcessorTest(Compiler.JDK) public void determinesAnimalKeyGetter() { AbstractAnimal source = new Elephant(); @@ -60,7 +49,7 @@ public void determinesAnimalKeyGetter() { assertThat( target.getAnimalKey().typeParameterIsResolvedToKeyOfAllBeings() ).isFalse(); } - @Test + @ProcessorTest public void determinesKeyOfAllBeingsGetter() { AbstractHuman source = new Child(); @@ -73,7 +62,7 @@ public void determinesKeyOfAllBeingsGetter() { assertThat( target.getKeyOfAllBeings().typeParameterIsResolvedToKeyOfAllBeings() ).isTrue(); } - @Test + @ProcessorTest public void determinesItemCSourceSetter() { Target target = new Target(); @@ -85,7 +74,7 @@ public void determinesItemCSourceSetter() { assertThat( source.getKey().typeParameterIsResolvedToAnimalKey() ).isTrue(); } - @Test + @ProcessorTest public void determinesItemBSourceSetter() { Target target = new Target(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/IAnimal.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/IAnimal.java index 2f585887a4..6b96c829d6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/IAnimal.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/IAnimal.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Identifiable.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Identifiable.java index 0b2c359b4a..4f3d7ca4a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Identifiable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Identifiable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Key.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Key.java index e43a551fc7..56e014d199 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Key.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Key.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/KeyOfAllBeings.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/KeyOfAllBeings.java index 75781ed94c..ab320ded50 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/KeyOfAllBeings.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/KeyOfAllBeings.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Target.java b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Target.java index 5dcf73c9c7..357e88a081 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/abstractclass/generics/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.abstractclass.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/AccessibilityTest.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/AccessibilityTest.java index f8145fab75..bab9ca9b71 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/AccessibilityTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/AccessibilityTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + import static java.lang.reflect.Modifier.isPrivate; import static java.lang.reflect.Modifier.isProtected; import static java.lang.reflect.Modifier.isPublic; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mapstruct.ap.testutil.IssueKey; -import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * Test for different accessibility modifiers @@ -35,10 +20,9 @@ * @author Andreas Gudian */ @WithClasses({ Source.class, Target.class, DefaultSourceTargetMapperAbstr.class, DefaultSourceTargetMapperIfc.class }) -@RunWith( AnnotationProcessorTestRunner.class ) public class AccessibilityTest { - @Test + @ProcessorTest @IssueKey("103") public void testGeneratedModifiersFromAbstractClassAreCorrect() throws Exception { Class defaultFromAbstract = loadForMapper( DefaultSourceTargetMapperAbstr.class ); @@ -50,14 +34,14 @@ public void testGeneratedModifiersFromAbstractClassAreCorrect() throws Exception assertTrue( isDefault( modifiersFor( defaultFromAbstract, "defaultSourceToTarget" ) ) ); } - @Test + @ProcessorTest @IssueKey("103") public void testGeneratedModifiersFromInterfaceAreCorrect() throws Exception { Class defaultFromIfc = loadForMapper( DefaultSourceTargetMapperIfc.class ); assertTrue( isDefault( defaultFromIfc.getModifiers() ) ); - assertTrue( isPublic( modifiersFor( defaultFromIfc, "implicitlyPublicSoureToTarget" ) ) ); + assertTrue( isPublic( modifiersFor( defaultFromIfc, "implicitlyPublicSourceToTarget" ) ) ); } private static Class loadForMapper(Class mapper) throws ClassNotFoundException { diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperAbstr.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperAbstr.java index 32bdd73554..d7f7ba46ba 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperAbstr.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperAbstr.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperIfc.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperIfc.java index fa983c4fb3..027d60b9ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperIfc.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/DefaultSourceTargetMapperIfc.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility; @@ -25,5 +12,5 @@ */ @Mapper interface DefaultSourceTargetMapperIfc { - Target implicitlyPublicSoureToTarget(Source source); + Target implicitlyPublicSourceToTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/Source.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/Source.java index 7d07a1691c..ab30881998 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/Target.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/Target.java index a5d198127a..253115abb0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperPrivate.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperPrivate.java index bb5261ddf6..2a16c3980f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperPrivate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperPrivate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; @@ -27,11 +14,11 @@ * @author Sjaak Derksen */ @Mapper -public abstract class AbstractSourceTargetMapperPrivate extends SourceTargetmapperPrivateBase { +public abstract class AbstractSourceTargetMapperPrivate extends SourceTargetMapperPrivateBase { public static final AbstractSourceTargetMapperPrivate INSTANCE = Mappers.getMapper( AbstractSourceTargetMapperPrivate.class ); - @Mapping(source = "referencedSource", target = "referencedTarget") + @Mapping(target = "referencedTarget", source = "referencedSource") public abstract Target toTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperProtected.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperProtected.java index ce2bb9d5d7..ccdba61514 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperProtected.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/AbstractSourceTargetMapperProtected.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; @@ -27,11 +14,11 @@ * @author Sjaak Derksen */ @Mapper -public abstract class AbstractSourceTargetMapperProtected extends SourceTargetmapperProtectedBase { +public abstract class AbstractSourceTargetMapperProtected extends SourceTargetMapperProtectedBase { public static final AbstractSourceTargetMapperProtected INSTANCE = Mappers.getMapper( AbstractSourceTargetMapperProtected.class ); - @Mapping(source = "referencedSource", target = "referencedTarget") + @Mapping(target = "referencedTarget", source = "referencedSource") public abstract Target toTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedAccessibilityTest.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedAccessibilityTest.java index 7f4bea7fa5..dc3d8ea10f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedAccessibilityTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedAccessibilityTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.accessibility.referenced.a.ReferencedMapperDefaultOther; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; /** @@ -36,13 +21,12 @@ * @author Sjaak Derksen */ @WithClasses( { Source.class, Target.class, ReferencedSource.class, ReferencedTarget.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class ReferencedAccessibilityTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @IssueKey("206") @WithClasses({ SourceTargetMapperPrivate.class, ReferencedMapperPrivate.class }) @ExpectedCompilationOutcome( @@ -50,27 +34,26 @@ public class ReferencedAccessibilityTest { diagnostics = { @Diagnostic(type = SourceTargetMapperPrivate.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 35, - messageRegExp = "Unmapped target property: \"bar\"\\. Mapping from property \"org\\.mapstruct\\.ap\\" + - ".test\\.accessibility\\.referenced\\.ReferencedSource referencedSource\" to \"org\\.mapstruct\\" + - ".ap\\.test\\.accessibility\\.referenced\\.ReferencedTarget referencedTarget\"") + line = 22, + message = "Unmapped target property: \"bar\". Mapping from property " + + "\"ReferencedSource referencedSource\" to \"ReferencedTarget referencedTarget\".") } ) - public void shouldNotBeAbleToAccessPrivateMethodInReferenced() throws Exception { + public void shouldNotBeAbleToAccessPrivateMethodInReferenced() { generatedSource.addComparisonToFixtureFor( SourceTargetMapperPrivate.class ); } - @Test + @ProcessorTest @IssueKey( "206" ) @WithClasses( { SourceTargetMapperDefaultSame.class, ReferencedMapperDefaultSame.class } ) - public void shouldBeAbleToAccessDefaultMethodInReferencedInSamePackage() throws Exception { } + public void shouldBeAbleToAccessDefaultMethodInReferencedInSamePackage() { } - @Test + @ProcessorTest @IssueKey( "206" ) @WithClasses( { SourceTargetMapperProtected.class, ReferencedMapperProtected.class } ) - public void shouldBeAbleToAccessProtectedMethodInReferencedInSamePackage() throws Exception { } + public void shouldBeAbleToAccessProtectedMethodInReferencedInSamePackage() { } - @Test + @ProcessorTest @IssueKey("206") @WithClasses({ SourceTargetMapperDefaultOther.class, ReferencedMapperDefaultOther.class }) @ExpectedCompilationOutcome( @@ -78,36 +61,34 @@ public void shouldBeAbleToAccessProtectedMethodInReferencedInSamePackage() throw diagnostics = { @Diagnostic(type = SourceTargetMapperDefaultOther.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 37, - messageRegExp = "Unmapped target property: \"bar\"\\. Mapping from property \"org\\.mapstruct\\.ap\\" + - ".test\\.accessibility\\.referenced\\.ReferencedSource referencedSource\" to \"org\\.mapstruct\\" + - ".ap\\.test\\.accessibility\\.referenced\\.ReferencedTarget referencedTarget\"") + line = 24, + message = "Unmapped target property: \"bar\". Mapping " + + "from property \"ReferencedSource referencedSource\" to \"ReferencedTarget referencedTarget\".") } ) - public void shouldNotBeAbleToAccessDefaultMethodInReferencedInOtherPackage() throws Exception { + public void shouldNotBeAbleToAccessDefaultMethodInReferencedInOtherPackage() { generatedSource.addComparisonToFixtureFor( SourceTargetMapperDefaultOther.class ); } - @Test + @ProcessorTest @IssueKey( "206" ) - @WithClasses( { AbstractSourceTargetMapperProtected.class, SourceTargetmapperProtectedBase.class } ) - public void shouldBeAbleToAccessProtectedMethodInBase() throws Exception { } + @WithClasses( { AbstractSourceTargetMapperProtected.class, SourceTargetMapperProtectedBase.class } ) + public void shouldBeAbleToAccessProtectedMethodInBase() { } - @Test + @ProcessorTest @IssueKey("206") - @WithClasses({ AbstractSourceTargetMapperPrivate.class, SourceTargetmapperPrivateBase.class }) + @WithClasses({ AbstractSourceTargetMapperPrivate.class, SourceTargetMapperPrivateBase.class }) @ExpectedCompilationOutcome( value = CompilationResult.SUCCEEDED, diagnostics = { @Diagnostic(type = AbstractSourceTargetMapperPrivate.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 36, - messageRegExp = "Unmapped target property: \"bar\"\\. Mapping from property \"org\\.mapstruct\\.ap\\" + - ".test\\.accessibility\\.referenced\\.ReferencedSource referencedSource\" to \"org\\.mapstruct\\" + - ".ap\\.test\\.accessibility\\.referenced\\.ReferencedTarget referencedTarget\"") + line = 23, + message = "Unmapped target property: \"bar\". Mapping from property " + + "\"ReferencedSource referencedSource\" to \"ReferencedTarget referencedTarget\".") } ) - public void shouldNotBeAbleToAccessPrivateMethodInBase() throws Exception { + public void shouldNotBeAbleToAccessPrivateMethodInBase() { generatedSource.addComparisonToFixtureFor( AbstractSourceTargetMapperPrivate.class ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperDefaultSame.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperDefaultSame.java index 499259f954..f572eee0a9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperDefaultSame.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperDefaultSame.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperPrivate.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperPrivate.java index 108af0ac2b..58e1336ca8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperPrivate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperPrivate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperProtected.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperProtected.java index d8a6931eba..389486ce4a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperProtected.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedMapperProtected.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedSource.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedSource.java index b0a75cf82d..e26969551e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedTarget.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedTarget.java index da13c64fb4..1dbfe510d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/ReferencedTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Source.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Source.java index 10a0f548dd..0b833a14ad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultOther.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultOther.java index e075d088d1..682a258e3d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultOther.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultOther.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; @@ -33,6 +20,6 @@ public interface SourceTargetMapperDefaultOther { SourceTargetMapperDefaultOther INSTANCE = Mappers.getMapper( SourceTargetMapperDefaultOther.class ); - @Mapping(source = "referencedSource", target = "referencedTarget") + @Mapping(target = "referencedTarget", source = "referencedSource") Target toTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultSame.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultSame.java index 56cc9aed08..536f45d5be 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultSame.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperDefaultSame.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; @@ -31,6 +18,6 @@ public interface SourceTargetMapperDefaultSame { SourceTargetMapperDefaultSame INSTANCE = Mappers.getMapper( SourceTargetMapperDefaultSame.class ); - @Mapping(source = "referencedSource", target = "referencedTarget") + @Mapping(target = "referencedTarget", source = "referencedSource") Target toTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivate.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivate.java index 9a7c080776..4615ff3e6f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; @@ -31,6 +18,6 @@ public interface SourceTargetMapperPrivate { SourceTargetMapperPrivate INSTANCE = Mappers.getMapper( SourceTargetMapperPrivate.class ); - @Mapping(source = "referencedSource", target = "referencedTarget") + @Mapping(target = "referencedTarget", source = "referencedSource") Target toTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivateBase.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivateBase.java new file mode 100644 index 0000000000..06dbb0cec7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperPrivateBase.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.accessibility.referenced; + +/** + * @author Sjaak Derksen + */ +public class SourceTargetMapperPrivateBase { + + @SuppressWarnings("unused") + private ReferencedTarget sourceToTarget(ReferencedSource source) { + ReferencedTarget target = new ReferencedTarget(); + target.setBar( source.getFoo() ); + return target; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtected.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtected.java index 6abd596936..c18c6127e4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtected.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtected.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; @@ -31,6 +18,6 @@ public interface SourceTargetMapperProtected { SourceTargetMapperProtected INSTANCE = Mappers.getMapper( SourceTargetMapperProtected.class ); - @Mapping(source = "referencedSource", target = "referencedTarget") + @Mapping(target = "referencedTarget", source = "referencedSource") Target toTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtectedBase.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtectedBase.java new file mode 100644 index 0000000000..fe5a50fa37 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetMapperProtectedBase.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.accessibility.referenced; + +/** + * + * @author Sjaak Derksen + */ +public class SourceTargetMapperProtectedBase { + + protected ReferencedTarget sourceToTarget( ReferencedSource source ) { + ReferencedTarget target = new ReferencedTarget(); + target.setBar( source.getFoo() ); + return target; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetmapperPrivateBase.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetmapperPrivateBase.java deleted file mode 100644 index 9264ac6a12..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetmapperPrivateBase.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.accessibility.referenced; - -/** - * @author Sjaak Derksen - */ -public class SourceTargetmapperPrivateBase { - - @SuppressWarnings("unused") - private ReferencedTarget sourceToTarget(ReferencedSource source) { - ReferencedTarget target = new ReferencedTarget(); - target.setBar( source.getFoo() ); - return target; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetmapperProtectedBase.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetmapperProtectedBase.java deleted file mode 100644 index 4435e81b5d..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/SourceTargetmapperProtectedBase.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.accessibility.referenced; - -/** - * - * @author Sjaak Derksen - */ -public class SourceTargetmapperProtectedBase { - - protected ReferencedTarget sourceToTarget( ReferencedSource source ) { - ReferencedTarget target = new ReferencedTarget(); - target.setBar( source.getFoo() ); - return target; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Target.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Target.java index ab2e74a024..50604a8075 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/a/ReferencedMapperDefaultOther.java b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/a/ReferencedMapperDefaultOther.java index 03ce8901b1..7d3ab7014f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/a/ReferencedMapperDefaultOther.java +++ b/processor/src/test/java/org/mapstruct/ap/test/accessibility/referenced/a/ReferencedMapperDefaultOther.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.accessibility.referenced.a; import org.mapstruct.ap.test.accessibility.referenced.ReferencedSource; import org.mapstruct.ap.test.accessibility.referenced.ReferencedTarget; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/AdditionalSupportedOptionsProviderTest.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/AdditionalSupportedOptionsProviderTest.java new file mode 100644 index 0000000000..ff2c85139f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/AdditionalSupportedOptionsProviderTest.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +import org.junit.jupiter.api.parallel.Execution; +import org.junit.jupiter.api.parallel.ExecutionMode; +import org.mapstruct.ap.spi.EnumMappingStrategy; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.Compiler; + +import static org.assertj.core.api.Assertions.assertThat; + +@Execution( ExecutionMode.CONCURRENT ) +public class AdditionalSupportedOptionsProviderTest { + + @ProcessorTest + @WithClasses({ + Pet.class, + PetWithMissing.class, + UnknownEnumMappingStrategyMapper.class + }) + @WithServiceImplementation(CustomAdditionalSupportedOptionsProvider.class) + @WithServiceImplementation(value = UnknownEnumMappingStrategy.class, provides = EnumMappingStrategy.class) + @ProcessorOption(name = "myorg.custom.defaultNullEnumConstant", value = "MISSING") + public void shouldUseConfiguredPrefix() { + assertThat( UnknownEnumMappingStrategyMapper.INSTANCE.map( null ) ) + .isEqualTo( PetWithMissing.MISSING ); + } + + @ProcessorTest(Compiler.JDK) // The eclipse compiler does not parse the error message properly + @WithClasses({ + EmptyMapper.class + }) + @WithServiceImplementation(InvalidAdditionalSupportedOptionsProvider.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + messageRegExp = "Additional SPI options cannot start with \"mapstruct\". Provider " + + "org.mapstruct.ap.test.additionalsupportedoptions.InvalidAdditionalSupportedOptionsProvider@.*" + + " provided option mapstruct.custom.test" + ) + ) + public void shouldFailWhenOptionsProviderUsesMapstructPrefix() { + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/CustomAdditionalSupportedOptionsProvider.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/CustomAdditionalSupportedOptionsProvider.java new file mode 100644 index 0000000000..87a994bb4e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/CustomAdditionalSupportedOptionsProvider.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +// tag::documentation[] +import java.util.Collections; +import java.util.Set; + +import org.mapstruct.ap.spi.AdditionalSupportedOptionsProvider; + +public class CustomAdditionalSupportedOptionsProvider implements AdditionalSupportedOptionsProvider { + + @Override + public Set getAdditionalSupportedOptions() { + return Collections.singleton( "myorg.custom.defaultNullEnumConstant" ); + } + +} +// end::documentation[] diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/EmptyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/EmptyMapper.java new file mode 100644 index 0000000000..13a6f0aece --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/EmptyMapper.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +import org.mapstruct.Mapper; + +@Mapper +public interface EmptyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/InvalidAdditionalSupportedOptionsProvider.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/InvalidAdditionalSupportedOptionsProvider.java new file mode 100644 index 0000000000..1a387abba2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/InvalidAdditionalSupportedOptionsProvider.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +import java.util.Collections; +import java.util.Set; + +import org.mapstruct.ap.spi.AdditionalSupportedOptionsProvider; + +public class InvalidAdditionalSupportedOptionsProvider implements AdditionalSupportedOptionsProvider { + + @Override + public Set getAdditionalSupportedOptions() { + return Collections.singleton( "mapstruct.custom.test" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/Pet.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/Pet.java new file mode 100644 index 0000000000..8fe9b39558 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/Pet.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +public enum Pet { + + DOG, + CAT, + BEAR + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/PetWithMissing.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/PetWithMissing.java new file mode 100644 index 0000000000..21d5f4a649 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/PetWithMissing.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +public enum PetWithMissing { + + DOG, + CAT, + BEAR, + MISSING + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/UnknownEnumMappingStrategy.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/UnknownEnumMappingStrategy.java new file mode 100644 index 0000000000..ca4403925e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/UnknownEnumMappingStrategy.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +// tag::documentation[] +import javax.lang.model.element.TypeElement; + +import org.mapstruct.ap.spi.DefaultEnumMappingStrategy; +import org.mapstruct.ap.spi.MapStructProcessingEnvironment; + +public class UnknownEnumMappingStrategy extends DefaultEnumMappingStrategy { + + private String defaultNullEnumConstant; + + @Override + public void init(MapStructProcessingEnvironment processingEnvironment) { + super.init( processingEnvironment ); + defaultNullEnumConstant = processingEnvironment.getOptions().get( "myorg.custom.defaultNullEnumConstant" ); + } + + @Override + public String getDefaultNullEnumConstant(TypeElement enumType) { + return defaultNullEnumConstant; + } +} +// end::documentation[] diff --git a/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/UnknownEnumMappingStrategyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/UnknownEnumMappingStrategyMapper.java new file mode 100644 index 0000000000..be8c74e227 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/additionalsupportedoptions/UnknownEnumMappingStrategyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.additionalsupportedoptions; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface UnknownEnumMappingStrategyMapper { + + UnknownEnumMappingStrategyMapper INSTANCE = Mappers.getMapper( UnknownEnumMappingStrategyMapper.class ); + + PetWithMissing map(Pet pet); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java new file mode 100644 index 0000000000..cc19c2d282 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateBeanMappingMethodMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateBeanMappingMethodMapper { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + Target map(Source source); + + class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java new file mode 100644 index 0000000000..86bef7de45 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateIterableMappingMethodMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.util.List; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateIterableMappingMethodMapper { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + List toStringList(List integers); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java new file mode 100644 index 0000000000..a972d5e06f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateMapMappingMethodMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.util.Date; +import java.util.Map; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateMapMappingMethodMapper { + + @MapMapping(valueDateFormat = "dd.MM.yyyy") + @AnnotateWith(CustomMethodOnlyAnnotation.class) + Map longDateMapToStringStringMap(Map source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java new file mode 100644 index 0000000000..6321b5590c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateStreamMappingMethodMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.util.stream.Stream; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateStreamMappingMethodMapper { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + Stream toStringStream(Stream integerStream); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java new file mode 100644 index 0000000000..a9e7c7b519 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateValueMappingMethodMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; + +/** + * @author orange add + */ +@Mapper +public interface AnnotateValueMappingMethodMapper { + + @ValueMappings({ + @ValueMapping(target = "EXISTING", source = "EXISTING"), + @ValueMapping( source = MappingConstants.ANY_REMAINING, target = "OTHER_EXISTING" ) + }) + @AnnotateWith(CustomMethodOnlyAnnotation.class) + AnnotateWithEnum map(String str); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithEnum.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithEnum.java new file mode 100644 index 0000000000..b2627fd8ce --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithEnum.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +public enum AnnotateWithEnum { + EXISTING, OTHER_EXISTING +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java new file mode 100644 index 0000000000..5dd6a6e8f5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotateWithTest.java @@ -0,0 +1,597 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.WithProperties; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Ben Zegveld + */ +@IssueKey("1574") +@WithClasses(AnnotateWithEnum.class) +public class AnnotateWithTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ DeprecateAndCustomMapper.class, CustomAnnotation.class }) + public void mapperBecomesDeprecatedAndGetsCustomAnnotation() { + DeprecateAndCustomMapper mapper = Mappers.getMapper( DeprecateAndCustomMapper.class ); + + assertThat( mapper.getClass() ).hasAnnotations( Deprecated.class, CustomAnnotation.class ); + } + + @ProcessorTest + @WithClasses( { + CustomNamedMapper.class, + CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class, + CustomClassOnlyAnnotation.class, + CustomMethodOnlyAnnotation.class, + } ) + public void annotationWithValue() { + generatedSource.addComparisonToFixtureFor( CustomNamedMapper.class ); + } + + @ProcessorTest + @WithClasses( { MultipleArrayValuesMapper.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void annotationWithMultipleValues() { + generatedSource.addComparisonToFixtureFor( MultipleArrayValuesMapper.class ); + } + + @ProcessorTest + @WithClasses( { CustomNamedGenericClassMapper.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void annotationWithCorrectGenericClassValue() { + CustomNamedGenericClassMapper mapper = Mappers.getMapper( CustomNamedGenericClassMapper.class ); + + CustomAnnotationWithParams annotation = mapper.getClass().getAnnotation( CustomAnnotationWithParams.class ); + assertThat( annotation ).isNotNull(); + assertThat( annotation.stringParam() ).isEqualTo( "test" ); + assertThat( annotation.genericTypedClass() ).isEqualTo( Mapper.class ); + } + + @ProcessorTest + @WithClasses( { AnnotationWithoutElementNameMapper.class, CustomAnnotation.class } ) + public void annotateWithoutElementName() { + generatedSource + .forMapper( AnnotationWithoutElementNameMapper.class ) + .content() + .contains( "@CustomAnnotation(value = \"value\")" ); + } + + @ProcessorTest + @WithClasses({ MetaAnnotatedMapper.class, ClassMetaAnnotation.class, CustomClassOnlyAnnotation.class }) + public void metaAnnotationWorks() { + MetaAnnotatedMapper mapper = Mappers.getMapper( MetaAnnotatedMapper.class ); + + assertThat( mapper.getClass() ).hasAnnotation( CustomClassOnlyAnnotation.class ); + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithMissingParameter.class, + line = 15, + message = "Parameter \"required\" is required for annotation \"AnnotationWithRequiredParameter\"." + ) + } + ) + @WithClasses({ ErroneousMapperWithMissingParameter.class, AnnotationWithRequiredParameter.class }) + public void erroneousMapperWithMissingParameter() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithMethodOnInterface.class, + line = 15, + message = "Annotation \"CustomMethodOnlyAnnotation\" is not allowed on classes." + ) + } + ) + @WithClasses({ ErroneousMapperWithMethodOnInterface.class, CustomMethodOnlyAnnotation.class }) + public void erroneousMapperWithMethodOnInterface() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithMethodOnClass.class, + line = 15, + message = "Annotation \"CustomMethodOnlyAnnotation\" is not allowed on classes." + ) + } + ) + @WithClasses({ ErroneousMapperWithMethodOnClass.class, CustomMethodOnlyAnnotation.class }) + public void erroneousMapperWithMethodOnClass() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithAnnotationOnlyOnInterface.class, + line = 15, + message = "Annotation \"CustomAnnotationOnlyAnnotation\" is not allowed on classes." + ) + } + ) + @WithClasses({ ErroneousMapperWithAnnotationOnlyOnInterface.class, CustomAnnotationOnlyAnnotation.class }) + public void erroneousMapperWithAnnotationOnlyOnInterface() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithAnnotationOnlyOnClass.class, + line = 15, + message = "Annotation \"CustomAnnotationOnlyAnnotation\" is not allowed on classes." + ) + } + ) + @WithClasses({ ErroneousMapperWithAnnotationOnlyOnClass.class, CustomAnnotationOnlyAnnotation.class }) + public void erroneousMapperWithAnnotationOnlyOnClass() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithClassOnMethod.class, + line = 18, + message = "Annotation \"CustomClassOnlyAnnotation\" is not allowed on methods." + ) + } + ) + @WithClasses({ ErroneousMapperWithClassOnMethod.class, CustomClassOnlyAnnotation.class, WithProperties.class }) + public void erroneousMapperWithClassOnMethod() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithUnknownParameter.class, + line = 17, + message = "Unknown parameter \"unknownParameter\" for annotation \"CustomAnnotation\"." + + " Did you mean \"value\"?" + ) + } + ) + @WithClasses({ ErroneousMapperWithUnknownParameter.class, CustomAnnotation.class }) + public void erroneousMapperWithUnknownParameter() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithNonExistantEnum.class, + line = 17, + message = "Enum \"AnnotateWithEnum\" does not have value \"NON_EXISTANT\"." + ) + } + ) + @WithClasses( { ErroneousMapperWithNonExistantEnum.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void erroneousMapperWithNonExistantEnum() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithTooManyParameterValues.class, + line = 17, + message = "Parameter \"stringParam\" has too many value types supplied, type \"String\" is expected" + + " for annotation \"CustomAnnotationWithParams\"." + ) + } + ) + @WithClasses( { ErroneousMapperWithTooManyParameterValues.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void erroneousMapperWithTooManyParameterValues() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 16, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"boolean\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 18, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"byte\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 20, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"char\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 22, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"CustomAnnotationWithParams\"" + + " but of type \"String\" for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 24, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"double\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 26, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"float\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 28, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"int\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 30, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"long\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 32, + alternativeLine = 43, + message = "Parameter \"stringParam\" is not of type \"short\" but of type \"String\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 35, + alternativeLine = 43, + message = "Parameter \"genericTypedClass\" is not of type \"String\" " + + "but of type \"Class\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 36, + alternativeLine = 43, + message = "Parameter \"enumParam\" is not of type \"WrongAnnotateWithEnum\" " + + "but of type \"AnnotateWithEnum\" for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 40, + alternativeLine = 43, + message = "Parameter \"genericTypedClass\" is not of type \"ErroneousMapperWithWrongParameter\" " + + "but of type \"Class\" " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithWrongParameter.class, + line = 42, + alternativeLine = 43, + message = "Parameter \"value\" is not of type \"boolean\" " + + "but of type \"String\" for annotation \"CustomAnnotation\"." + ) + } + ) + @WithClasses({ + ErroneousMapperWithWrongParameter.class, CustomAnnotationWithParams.class, + CustomAnnotationWithParamsContainer.class, WrongAnnotateWithEnum.class, CustomAnnotation.class + }) + public void erroneousMapperWithWrongParameter() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 17, + alternativeLine = 43, + message = "Parameter \"stringParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 18, + alternativeLine = 43, + message = "Parameter \"booleanParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 19, + alternativeLine = 32, + message = "Parameter \"byteParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 20, + alternativeLine = 32, + message = "Parameter \"charParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 21, + alternativeLine = 32, + message = "Parameter \"doubleParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 22, + alternativeLine = 32, + message = "Parameter \"floatParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 23, + alternativeLine = 32, + message = "Parameter \"intParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 24, + alternativeLine = 32, + message = "Parameter \"longParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 25, + alternativeLine = 32, + message = "Parameter \"shortParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 26, + alternativeLine = 32, + message = "Parameter \"genericTypedClass\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMultipleArrayValuesMapper.class, + line = 27, + alternativeLine = 32, + message = "Parameter \"enumParam\" does not accept multiple values " + + "for annotation \"CustomAnnotationWithParams\"." + ) + } + ) + @WithClasses( { ErroneousMultipleArrayValuesMapper.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void erroneousMapperUsingMultipleValuesInsteadOfSingle() { + } + + @ProcessorTest + @WithClasses( { MapperWithMissingAnnotationElementName.class, + CustomAnnotationWithTwoAnnotationElements.class } ) + public void mapperWithMissingAnnotationElementNameShouldCompile() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithMissingEnumClass.class, + line = 17, + message = "enumClass needs to be defined when using enums." + ) + } + ) + @WithClasses( { ErroneousMapperWithMissingEnumClass.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void erroneousMapperWithMissingEnumClass() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithMissingEnums.class, + line = 17, + message = "enums needs to be defined when using enumClass." + ) + } + ) + @WithClasses( { ErroneousMapperWithMissingEnums.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void erroneousMapperWithMissingEnums() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithRepeatOfNotRepeatableAnnotation.class, + line = 16, + alternativeLine = 17, + message = "Annotation \"CustomAnnotation\" is not repeatable." + ) + } + ) + @WithClasses( { ErroneousMapperWithRepeatOfNotRepeatableAnnotation.class, CustomAnnotation.class } ) + public void erroneousMapperWithRepeatOfNotRepeatableAnnotation() { + } + + @ProcessorTest + @WithClasses( { MapperWithRepeatableAnnotation.class, CustomRepeatableAnnotation.class, + CustomRepeatableAnnotationContainer.class } ) + public void mapperWithRepeatableAnnotationShouldCompile() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapperWithParameterRepeat.class, + line = 18, + message = "Parameter \"stringParam\" must not be defined more than once." + ) + } + ) + @WithClasses( { ErroneousMapperWithParameterRepeat.class, CustomAnnotationWithParamsContainer.class, + CustomAnnotationWithParams.class } ) + public void erroneousMapperWithParameterRepeat() { + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + type = MapperWithIdenticalAnnotationRepeated.class, + line = 16, + alternativeLine = 17, + message = "Annotation \"CustomRepeatableAnnotation\" is already present " + + "with the same elements configuration." + ) + } + ) + @WithClasses( { MapperWithIdenticalAnnotationRepeated.class, CustomRepeatableAnnotation.class, + CustomRepeatableAnnotationContainer.class } ) + public void mapperWithIdenticalAnnotationRepeated() { + } + + @ProcessorTest + @WithClasses( {AnnotateBeanMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void beanMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateBeanMappingMethodMapper mapper = Mappers.getMapper( AnnotateBeanMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "map", AnnotateBeanMappingMethodMapper.Source.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateIterableMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void iterableMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateIterableMappingMethodMapper mapper = Mappers.getMapper( AnnotateIterableMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "toStringList", List.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateMapMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void mapMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateMapMappingMethodMapper mapper = Mappers.getMapper( AnnotateMapMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "longDateMapToStringStringMap", Map.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateStreamMappingMethodMapper.class, CustomMethodOnlyAnnotation.class} ) + public void streamMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateStreamMappingMethodMapper mapper = Mappers.getMapper( AnnotateStreamMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "toStringStream", Stream.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } + + @ProcessorTest + @WithClasses( {AnnotateValueMappingMethodMapper.class, AnnotateWithEnum.class, CustomMethodOnlyAnnotation.class} ) + public void valueMappingMethodWithCorrectCustomAnnotation() throws NoSuchMethodException { + AnnotateValueMappingMethodMapper mapper = Mappers.getMapper( AnnotateValueMappingMethodMapper.class ); + Method method = mapper.getClass().getMethod( "map", String.class ); + assertThat( method.getAnnotation( CustomMethodOnlyAnnotation.class ) ).isNotNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotationWithRequiredParameter.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotationWithRequiredParameter.java new file mode 100644 index 0000000000..183b865928 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotationWithRequiredParameter.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE, METHOD } ) +public @interface AnnotationWithRequiredParameter { + String required(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotationWithoutElementNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotationWithoutElementNameMapper.java new file mode 100644 index 0000000000..8bb83ba562 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/AnnotationWithoutElementNameMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +@Mapper +@AnnotateWith( value = CustomAnnotation.class, elements = @AnnotateWith.Element( strings = "value" ) ) +public interface AnnotationWithoutElementNameMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ClassMetaAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ClassMetaAnnotation.java new file mode 100644 index 0000000000..057cb384fb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ClassMetaAnnotation.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.AnnotateWith; + +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.TYPE } ) +@AnnotateWith( CustomClassOnlyAnnotation.class ) +public @interface ClassMetaAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotation.java new file mode 100644 index 0000000000..71ee6f12e3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotation.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE, METHOD } ) +public @interface CustomAnnotation { + String value() default ""; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationOnlyAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationOnlyAnnotation.java new file mode 100644 index 0000000000..52d3e386a0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationOnlyAnnotation.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.ANNOTATION_TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention(RUNTIME) +@Target({ ANNOTATION_TYPE }) +public @interface CustomAnnotationOnlyAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithParams.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithParams.java new file mode 100644 index 0000000000..bc25302fc1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithParams.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { METHOD, TYPE } ) +@Repeatable( CustomAnnotationWithParamsContainer.class ) +public @interface CustomAnnotationWithParams { + String stringParam(); + + Class genericTypedClass() default CustomAnnotationWithParams.class; + + AnnotateWithEnum enumParam() default AnnotateWithEnum.EXISTING; + + byte byteParam() default 0x00; + + char charParam() default 'a'; + + double doubleParam() default 0.0; + + float floatParam() default 0.0f; + + int intParam() default 0; + + long longParam() default 0L; + + short shortParam() default 0; + + boolean booleanParam() default false; + + short[] shortArray() default {}; + + byte[] byteArray() default {}; + + int[] intArray() default {}; + + long[] longArray() default {}; + + float[] floatArray() default {}; + + double[] doubleArray() default {}; + + char[] charArray() default {}; + + boolean[] booleanArray() default {}; + + String[] stringArray() default {}; + + Class[] classArray() default {}; + + AnnotateWithEnum[] enumArray() default {}; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithParamsContainer.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithParamsContainer.java new file mode 100644 index 0000000000..51ed62885c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithParamsContainer.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE, METHOD } ) +public @interface CustomAnnotationWithParamsContainer { + CustomAnnotationWithParams[] value() default {}; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithTwoAnnotationElements.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithTwoAnnotationElements.java new file mode 100644 index 0000000000..fb8c5c69f8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomAnnotationWithTwoAnnotationElements.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE, METHOD } ) +public @interface CustomAnnotationWithTwoAnnotationElements { + String value() default ""; + boolean namedAnnotationElement() default false; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomClassOnlyAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomClassOnlyAnnotation.java new file mode 100644 index 0000000000..858c8fb52f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomClassOnlyAnnotation.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE } ) +public @interface CustomClassOnlyAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomMethodOnlyAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomMethodOnlyAnnotation.java new file mode 100644 index 0000000000..1dfe8e734e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomMethodOnlyAnnotation.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { METHOD } ) +public @interface CustomMethodOnlyAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomNamedGenericClassMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomNamedGenericClassMapper.java new file mode 100644 index 0000000000..a320d56bba --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomNamedGenericClassMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @Element( name = "stringParam", strings = "test" ), + @Element( name = "genericTypedClass", classes = Mapper.class ) +} ) +public interface CustomNamedGenericClassMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomNamedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomNamedMapper.java new file mode 100644 index 0000000000..9f48d8c764 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomNamedMapper.java @@ -0,0 +1,78 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( CustomClassOnlyAnnotation.class ) +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @Element( name = "stringArray", strings = "test" ), + @Element( name = "stringParam", strings = "test" ), + @Element( name = "booleanArray", booleans = true ), + @Element( name = "booleanParam", booleans = true ), + @Element( name = "byteArray", bytes = 0x10 ), + @Element( name = "byteParam", bytes = 0x13 ), + @Element( name = "charArray", chars = 'd' ), + @Element( name = "charParam", chars = 'a' ), + @Element( name = "enumArray", enumClass = AnnotateWithEnum.class, enums = "EXISTING" ), + @Element( name = "enumParam", enumClass = AnnotateWithEnum.class, enums = "EXISTING" ), + @Element( name = "doubleArray", doubles = 0.3 ), + @Element( name = "doubleParam", doubles = 1.2 ), + @Element( name = "floatArray", floats = 0.3f ), + @Element( name = "floatParam", floats = 1.2f ), + @Element( name = "intArray", ints = 3 ), + @Element( name = "intParam", ints = 1 ), + @Element( name = "longArray", longs = 3L ), + @Element( name = "longParam", longs = 1L ), + @Element( name = "shortArray", shorts = 3 ), + @Element( name = "shortParam", shorts = 1 ) +} ) +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @Element(name = "stringParam", strings = "single value") +}) +public interface CustomNamedMapper { + + @AnnotateWith(value = CustomAnnotationWithParams.class, elements = { + @Element(name = "stringParam", strings = "double method value"), + @Element(name = "stringArray", strings = { "first", "second" }), + }) + @AnnotateWith(value = CustomAnnotationWithParams.class, elements = { + @Element(name = "stringParam", strings = "single method value") + }) + @AnnotateWith( CustomMethodOnlyAnnotation.class ) + Target map(Source source); + + class Target { + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomRepeatableAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomRepeatableAnnotation.java new file mode 100644 index 0000000000..d7c0c85107 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomRepeatableAnnotation.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE, METHOD } ) +@Repeatable( CustomRepeatableAnnotationContainer.class ) +public @interface CustomRepeatableAnnotation { + String value() default ""; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomRepeatableAnnotationContainer.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomRepeatableAnnotationContainer.java new file mode 100644 index 0000000000..8de3a8bf0a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/CustomRepeatableAnnotationContainer.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.METHOD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +@Retention( RUNTIME ) +@Target( { TYPE, METHOD } ) +public @interface CustomRepeatableAnnotationContainer { + CustomRepeatableAnnotation[] value() default {}; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/DeprecateAndCustomMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/DeprecateAndCustomMapper.java new file mode 100644 index 0000000000..809ad5702a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/DeprecateAndCustomMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( Deprecated.class ) +@AnnotateWith( CustomAnnotation.class ) +public interface DeprecateAndCustomMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithAnnotationOnlyOnClass.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithAnnotationOnlyOnClass.java new file mode 100644 index 0000000000..d617e8d0fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithAnnotationOnlyOnClass.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +@AnnotateWith( value = CustomAnnotationOnlyAnnotation.class ) +public abstract class ErroneousMapperWithAnnotationOnlyOnClass { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithAnnotationOnlyOnInterface.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithAnnotationOnlyOnInterface.java new file mode 100644 index 0000000000..4e914b30a3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithAnnotationOnlyOnInterface.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +@AnnotateWith( value = CustomAnnotationOnlyAnnotation.class ) +public interface ErroneousMapperWithAnnotationOnlyOnInterface { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithClassOnMethod.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithClassOnMethod.java new file mode 100644 index 0000000000..c34bce304f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithClassOnMethod.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.WithProperties; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface ErroneousMapperWithClassOnMethod { + + @AnnotateWith( value = CustomClassOnlyAnnotation.class ) + WithProperties toString(String string); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMethodOnClass.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMethodOnClass.java new file mode 100644 index 0000000000..262880d6f5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMethodOnClass.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomMethodOnlyAnnotation.class ) +public abstract class ErroneousMapperWithMethodOnClass { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMethodOnInterface.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMethodOnInterface.java new file mode 100644 index 0000000000..75f9039093 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMethodOnInterface.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomMethodOnlyAnnotation.class ) +public interface ErroneousMapperWithMethodOnInterface { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingEnumClass.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingEnumClass.java new file mode 100644 index 0000000000..6905a363f2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingEnumClass.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = { @Element( name = "enumParam", enums = "EXISTING" ), + @Element( name = "stringParam", strings = "required" ) } +) +public interface ErroneousMapperWithMissingEnumClass { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingEnums.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingEnums.java new file mode 100644 index 0000000000..fc7096d290 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingEnums.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @Element( name = "stringParam", strings = "required", enumClass = AnnotateWithEnum.class ) +) +public interface ErroneousMapperWithMissingEnums { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingParameter.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingParameter.java new file mode 100644 index 0000000000..40ffa53094 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithMissingParameter.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( AnnotationWithRequiredParameter.class ) +public interface ErroneousMapperWithMissingParameter { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithNonExistantEnum.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithNonExistantEnum.java new file mode 100644 index 0000000000..1ed85b990d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithNonExistantEnum.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = { @Element( name = "enumParam", enumClass = AnnotateWithEnum.class, enums = "NON_EXISTANT" ), + @Element( name = "stringParam", strings = "required" ) } +) +public interface ErroneousMapperWithNonExistantEnum { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithParameterRepeat.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithParameterRepeat.java new file mode 100644 index 0000000000..d75c7a4ee4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithParameterRepeat.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @Element( name = "stringParam", strings = "test" ), + @Element( name = "stringParam", strings = "otherValue" ) +} ) +public interface ErroneousMapperWithParameterRepeat { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithRepeatOfNotRepeatableAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithRepeatOfNotRepeatableAnnotation.java new file mode 100644 index 0000000000..be9596ea46 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithRepeatOfNotRepeatableAnnotation.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotation.class ) +@AnnotateWith( value = CustomAnnotation.class ) +public interface ErroneousMapperWithRepeatOfNotRepeatableAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithTooManyParameterValues.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithTooManyParameterValues.java new file mode 100644 index 0000000000..4b6c20c39b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithTooManyParameterValues.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @Element( name = "stringParam", booleans = true, strings = "test" ) +) +public interface ErroneousMapperWithTooManyParameterValues { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithUnknownParameter.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithUnknownParameter.java new file mode 100644 index 0000000000..c705dc88f7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithUnknownParameter.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotation.class, + elements = @Element( name = "unknownParameter", strings = "unknown" ) +) +public interface ErroneousMapperWithUnknownParameter { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithWrongParameter.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithWrongParameter.java new file mode 100644 index 0000000000..3251122b22 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMapperWithWrongParameter.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", booleans = true ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", bytes = 0x12 ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", chars = 'a' ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", classes = CustomAnnotationWithParams.class ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", doubles = 12.34 ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", floats = 12.34f ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", ints = 1234 ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", longs = 1234L ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, + elements = @AnnotateWith.Element( name = "stringParam", shorts = 12 ) ) +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @AnnotateWith.Element( name = "stringParam", strings = "correctValue" ), + @AnnotateWith.Element( name = "genericTypedClass", strings = "wrong" ), + @AnnotateWith.Element( name = "enumParam", enumClass = WrongAnnotateWithEnum.class, enums = "EXISTING" ) +} ) +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @AnnotateWith.Element( name = "stringParam", strings = "correctValue" ), + @AnnotateWith.Element( name = "genericTypedClass", classes = ErroneousMapperWithWrongParameter.class ) +} ) +@AnnotateWith( value = CustomAnnotation.class, elements = @AnnotateWith.Element( booleans = true ) ) +public interface ErroneousMapperWithWrongParameter { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMultipleArrayValuesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMultipleArrayValuesMapper.java new file mode 100644 index 0000000000..f6bf7629cd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/ErroneousMultipleArrayValuesMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @Element( name = "stringParam", strings = { "test1", "test2" } ), + @Element( name = "booleanParam", booleans = { false, true } ), + @Element( name = "byteParam", bytes = { 0x08, 0x1f } ), + @Element( name = "charParam", chars = { 'b', 'c' } ), + @Element( name = "doubleParam", doubles = { 1.2, 3.4 } ), + @Element( name = "floatParam", floats = { 1.2f, 3.4f } ), + @Element( name = "intParam", ints = { 12, 34 } ), + @Element( name = "longParam", longs = { 12L, 34L } ), + @Element( name = "shortParam", shorts = { 12, 34 } ), + @Element( name = "genericTypedClass", classes = { Mapper.class, CustomAnnotationWithParams.class } ), + @Element( name = "enumParam", enumClass = AnnotateWithEnum.class, enums = { "EXISTING", "OTHER_EXISTING" } ) +} ) +public interface ErroneousMultipleArrayValuesMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithIdenticalAnnotationRepeated.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithIdenticalAnnotationRepeated.java new file mode 100644 index 0000000000..0959ee305a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithIdenticalAnnotationRepeated.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomRepeatableAnnotation.class, elements = @AnnotateWith.Element( strings = "identical" ) ) +@AnnotateWith( value = CustomRepeatableAnnotation.class, elements = @AnnotateWith.Element( strings = "identical" ) ) +public interface MapperWithIdenticalAnnotationRepeated { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithMissingAnnotationElementName.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithMissingAnnotationElementName.java new file mode 100644 index 0000000000..ed9523c545 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithMissingAnnotationElementName.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithTwoAnnotationElements.class, elements = { + @AnnotateWith.Element( strings = "unnamed annotation element" ), + @AnnotateWith.Element( name = "namedAnnotationElement", booleans = false ) +} ) +public abstract class MapperWithMissingAnnotationElementName { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithRepeatableAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithRepeatableAnnotation.java new file mode 100644 index 0000000000..b66ec68261 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MapperWithRepeatableAnnotation.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomRepeatableAnnotation.class ) +@AnnotateWith( value = CustomRepeatableAnnotation.class, elements = @AnnotateWith.Element( strings = "different" ) ) +public interface MapperWithRepeatableAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MetaAnnotatedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MetaAnnotatedMapper.java new file mode 100644 index 0000000000..2dddb17f83 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MetaAnnotatedMapper.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.Mapper; + +@ClassMetaAnnotation +@Mapper +public interface MetaAnnotatedMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MethodMetaAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MethodMetaAnnotation.java new file mode 100644 index 0000000000..a93d54c283 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MethodMetaAnnotation.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.AnnotateWith; + +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.METHOD } ) +@AnnotateWith( CustomMethodOnlyAnnotation.class ) +public @interface MethodMetaAnnotation { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MultipleArrayValuesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MultipleArrayValuesMapper.java new file mode 100644 index 0000000000..2ccdbb0ea2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/MultipleArrayValuesMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.AnnotateWith.Element; +import org.mapstruct.Mapper; + +/** + * @author Ben Zegveld + */ +@Mapper +@AnnotateWith( value = CustomAnnotationWithParams.class, elements = { + @Element( name = "stringArray", strings = { "test1", "test2" } ), + @Element( name = "booleanArray", booleans = { false, true } ), + @Element( name = "byteArray", bytes = { 0x08, 0x1f } ), + @Element( name = "charArray", chars = { 'b', 'c' } ), + @Element( name = "doubleArray", doubles = { 1.2, 3.4 } ), + @Element( name = "floatArray", floats = { 1.2f, 3.4f } ), + @Element( name = "intArray", ints = { 12, 34 } ), + @Element( name = "longArray", longs = { 12L, 34L } ), + @Element( name = "shortArray", shorts = { 12, 34 } ), + @Element( name = "classArray", classes = { Mapper.class, CustomAnnotationWithParams.class } ), + @Element( name = "stringParam", strings = "required parameter" ) +} ) +public interface MultipleArrayValuesMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/WrongAnnotateWithEnum.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/WrongAnnotateWithEnum.java new file mode 100644 index 0000000000..677a6cc6d5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/WrongAnnotateWithEnum.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith; + +public enum WrongAnnotateWithEnum { + EXISTING +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedMapperWithClass.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedMapperWithClass.java new file mode 100644 index 0000000000..d0164e8be0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedMapperWithClass.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated; + +import org.mapstruct.Mapper; + +@Mapper +@Deprecated +public class DeprecatedMapperWithClass { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedMapperWithMethod.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedMapperWithMethod.java new file mode 100644 index 0000000000..b6c2c8eb62 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedMapperWithMethod.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation; + +@Mapper +public interface DeprecatedMapperWithMethod { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + @Deprecated + Target map(Source source); + + class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedTest.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedTest.java new file mode 100644 index 0000000000..42bb5d9ce5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/DeprecatedTest.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated; + +import java.lang.reflect.Method; + +import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author orange add + */ +public class DeprecatedTest { + + @ProcessorTest + @WithClasses( { DeprecatedMapperWithMethod.class, CustomMethodOnlyAnnotation.class} ) + public void deprecatedWithMethodCorrectCopy() throws NoSuchMethodException { + DeprecatedMapperWithMethod mapper = Mappers.getMapper( DeprecatedMapperWithMethod.class ); + Method method = mapper.getClass().getMethod( "map", DeprecatedMapperWithMethod.Source.class ); + Deprecated annotation = method.getAnnotation( Deprecated.class ); + assertThat( annotation ).isNotNull(); + } + + @ProcessorTest + @WithClasses(DeprecatedMapperWithClass.class) + public void deprecatedWithClassCorrectCopy() { + DeprecatedMapperWithClass mapper = Mappers.getMapper( DeprecatedMapperWithClass.class ); + Deprecated annotation = mapper.getClass().getAnnotation( Deprecated.class ); + assertThat( annotation ).isNotNull(); + } + + @ProcessorTest + @WithClasses(RepeatDeprecatedMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + type = RepeatDeprecatedMapper.class, + message = "Annotation \"Deprecated\" is already present with the " + + "same elements configuration." + ) + } + ) + public void deprecatedWithRepeat() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/RepeatDeprecatedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/RepeatDeprecatedMapper.java new file mode 100644 index 0000000000..dd085f101c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/RepeatDeprecatedMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +@Mapper +@Deprecated +@AnnotateWith(Deprecated.class) +public class RepeatDeprecatedMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedMapperWithClass.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedMapperWithClass.java new file mode 100644 index 0000000000..2e0507f5ab --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedMapperWithClass.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated.jdk11; + +import org.mapstruct.Mapper; + +@Mapper +@Deprecated(since = "11") +public class DeprecatedMapperWithClass { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedMapperWithMethod.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedMapperWithMethod.java new file mode 100644 index 0000000000..bf898e2043 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedMapperWithMethod.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated.jdk11; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation; + +@Mapper +public interface DeprecatedMapperWithMethod { + + @AnnotateWith(CustomMethodOnlyAnnotation.class) + @Deprecated(since = "18", forRemoval = false) + Target map(Source source); + + class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedTest.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedTest.java new file mode 100644 index 0000000000..dc496a22fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/DeprecatedTest.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated.jdk11; + +import java.lang.reflect.Method; + +import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author orange add + */ +public class DeprecatedTest { + @ProcessorTest + @WithClasses({ DeprecatedMapperWithMethod.class, CustomMethodOnlyAnnotation.class}) + public void deprecatedWithMethodCorrectCopyForJdk11() throws NoSuchMethodException { + DeprecatedMapperWithMethod mapper = Mappers.getMapper( DeprecatedMapperWithMethod.class ); + Method method = mapper.getClass().getMethod( "map", DeprecatedMapperWithMethod.Source.class ); + Deprecated annotation = method.getAnnotation( Deprecated.class ); + assertThat( annotation ).isNotNull(); + assertThat( annotation.since() ).isEqualTo( "18" ); + assertThat( annotation.forRemoval() ).isEqualTo( false ); + } + + @ProcessorTest + @WithClasses(DeprecatedMapperWithClass.class) + public void deprecatedWithClassCorrectCopyForJdk11() { + DeprecatedMapperWithClass mapper = Mappers.getMapper( DeprecatedMapperWithClass.class ); + Deprecated annotation = mapper.getClass().getAnnotation( Deprecated.class ); + assertThat( annotation ).isNotNull(); + assertThat( annotation.since() ).isEqualTo( "11" ); + } + + @ProcessorTest + @WithClasses( { RepeatDeprecatedMapperWithParams.class}) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + type = RepeatDeprecatedMapperWithParams.class, + message = "Annotation \"Deprecated\" is already present with the " + + "same elements configuration." + ) + } + ) + public void bothExistPriorityAnnotateWithForJdk11() { + RepeatDeprecatedMapperWithParams mapper = Mappers.getMapper( RepeatDeprecatedMapperWithParams.class ); + Deprecated deprecated = mapper.getClass().getAnnotation( Deprecated.class ); + assertThat( deprecated ).isNotNull(); + assertThat( deprecated.since() ).isEqualTo( "1.5" ); + assertThat( deprecated.forRemoval() ).isEqualTo( false ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/RepeatDeprecatedMapperWithParams.java b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/RepeatDeprecatedMapperWithParams.java new file mode 100644 index 0000000000..971791bfd2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/annotatewith/deprecated/jdk11/RepeatDeprecatedMapperWithParams.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.annotatewith.deprecated.jdk11; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; + +@Mapper +@Deprecated( since = "1.8" ) +@AnnotateWith( + value = Deprecated.class, + elements = { + @AnnotateWith.Element( name = "forRemoval", booleans = false), + @AnnotateWith.Element( name = "since", strings = "1.5") + } +) +public class RepeatDeprecatedMapperWithParams { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/array/ArrayMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/array/ArrayMappingTest.java index d908b3102b..fe33893417 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/array/ArrayMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/array/ArrayMappingTest.java @@ -1,48 +1,35 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.array; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; import java.util.List; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.array._target.GenericScientistDto; import org.mapstruct.ap.test.array._target.ScientistDto; +import org.mapstruct.ap.test.array.source.GenericScientist; import org.mapstruct.ap.test.array.source.Scientist; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; -@WithClasses( { Scientist.class, ScientistDto.class, ScienceMapper.class } ) -@RunWith(AnnotationProcessorTestRunner.class) +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses( { Scientist.class, ScientistDto.class, GenericScientist.class, GenericScientistDto.class, + ScienceMapper.class } ) @IssueKey("108") public class ArrayMappingTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource() + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() .addComparisonToFixtureFor( ScienceMapper.class ); - @Test + @ProcessorTest public void shouldCopyArraysInBean() { Scientist source = new Scientist("Bob"); @@ -57,7 +44,7 @@ public void shouldCopyArraysInBean() { assertThat( dto.publicPublications ).containsOnly( "public the Lancet", "public Nature" ); } - @Test + @ProcessorTest public void shouldForgeMappingForIntToString() { Scientist source = new Scientist("Bob"); @@ -71,34 +58,138 @@ public void shouldForgeMappingForIntToString() { assertThat( dto.publicPublicationYears ).containsOnly( 1994, 1998 ); } - @Test - public void shouldMapArrayToArray() { + @ProcessorTest + public void shouldMapArrayToArrayAndNullToNull() { + ScientistDto[] dtos = ScienceMapper.INSTANCE + .scientistsToDtosReturnNull( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.scientistsToDtosReturnNull( (Scientist[]) null ) ).isNull(); + } + + @ProcessorTest + public void shouldMapArrayToArrayAndNullToDefault() { ScientistDto[] dtos = ScienceMapper.INSTANCE - .scientistsToDtos( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } ); + .scientistsToDtosReturnDefault( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } ); assertThat( dtos ).isNotNull(); assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.scientistsToDtosReturnDefault( (Scientist[]) null ) ).isEmpty(); } - @Test - public void shouldMapListToArray() { + @ProcessorTest + public void shouldMapListToArrayAndNullToNull() { ScientistDto[] dtos = ScienceMapper.INSTANCE - .scientistsToDtos( Arrays.asList( new Scientist( "Bob" ), new Scientist( "Larry" ) ) ); + .scientistsToDtosReturnNull( Arrays.asList( new Scientist( "Bob" ), new Scientist( "Larry" ) ) ); assertThat( dtos ).isNotNull(); assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.scientistsToDtosReturnNull( (List) null ) ).isNull(); } - @Test - public void shouldMapArrayToList() { + @ProcessorTest + public void shouldMapListToArrayAndNullToDefault() { + ScientistDto[] dtos = ScienceMapper.INSTANCE + .scientistsToDtosReturnDefault( Arrays.asList( new Scientist( "Bob" ), new Scientist( "Larry" ) ) ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.scientistsToDtosReturnDefault( (List) null ) ).isEmpty(); + } + + @ProcessorTest + public void shouldMapArrayToListAndNullToNull() { List dtos = ScienceMapper.INSTANCE - .scientistsToDtosAsList( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } ); + .scientistsToDtosAsListReturnNull( new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } ); assertThat( dtos ).isNotNull(); assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.scientistsToDtosAsListReturnNull( null ) ).isNull(); } - @Test + @ProcessorTest + public void shouldMapArrayToListAndNullToDefault() { + List dtos = ScienceMapper.INSTANCE + .scientistsToDtosAsListReturnDefault( + new Scientist[]{ new Scientist( "Bob" ), new Scientist( "Larry" ) } ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.scientistsToDtosAsListReturnDefault( null ) ).isEmpty(); + } + + @ProcessorTest + @SuppressWarnings("unchecked") + public void shouldMapGenericArrayToGenericArrayAndNullToNull() { + GenericScientistDto[] dtos = ScienceMapper.INSTANCE + .genericScientistToDtosReturnNull( + new GenericScientist[]{ new GenericScientist<>( "Bob" ), new GenericScientist<>( "Larry" ) } ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.genericScientistToDtosReturnNull( (GenericScientist[]) null ) ) + .isNull(); + } + + @ProcessorTest + @SuppressWarnings("unchecked") + public void shouldMapGenericArrayToGenericArrayAndNullToDefault() { + GenericScientistDto[] dtos = ScienceMapper.INSTANCE.genericScientistToDtosReturnDefault( + new GenericScientist[]{ new GenericScientist<>( "Bob" ), new GenericScientist<>( "Larry" ) } ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.genericScientistToDtosReturnDefault( (GenericScientist[]) null ) ) + .isEmpty(); + } + + @ProcessorTest + public void shouldMapListToGenericArrayAndNullToNull() { + GenericScientistDto[] dtos = ScienceMapper.INSTANCE.genericScientistToDtosReturnNull( + Arrays.asList( new GenericScientist<>( "Bob" ), new GenericScientist<>( "Larry" ) ) ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.genericScientistToDtosReturnNull( (List>) null ) ) + .isNull(); + } + + @ProcessorTest + public void shouldMapListToGenericArrayAndNullToDefault() { + GenericScientistDto[] dtos = ScienceMapper.INSTANCE + .genericScientistToDtosReturnDefault( + Arrays.asList( new GenericScientist<>("Bob"), new GenericScientist<>( "Larry" ) ) ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE + .genericScientistToDtosReturnDefault( (List>) null ) ).isEmpty(); + } + + @ProcessorTest + @SuppressWarnings("unchecked") + public void shouldMapGenericArrayToListAndNullToNull() { + List> dtos = ScienceMapper.INSTANCE.genericScientistToDtosAsList( + new GenericScientist[]{ new GenericScientist<>( "Bob" ), new GenericScientist<>( "Larry" ) } ); + + assertThat( dtos ).isNotNull(); + assertThat( dtos ).extracting( "name" ).containsOnly( "Bob", "Larry" ); + + assertThat( ScienceMapper.INSTANCE.genericScientistToDtosAsList( null ) ).isNull(); + } + + @ProcessorTest public void shouldMapArrayToArrayExistingSmallerSizedTarget() { ScientistDto[] existingTarget = new ScientistDto[]{ new ScientistDto( "Jim" ) }; @@ -111,7 +202,7 @@ public void shouldMapArrayToArrayExistingSmallerSizedTarget() { assertThat( target ).extracting( "name" ).containsOnly( "Bob" ); } - @Test + @ProcessorTest public void shouldMapArrayToArrayExistingEqualSizedTarget() { ScientistDto[] existingTarget = new ScientistDto[]{ new ScientistDto( "Jim" ), new ScientistDto( "Bart" ) }; @@ -124,7 +215,7 @@ public void shouldMapArrayToArrayExistingEqualSizedTarget() { assertThat( target ).extracting( "name" ).containsOnly( "Bob", "Larry" ); } - @Test + @ProcessorTest public void shouldMapArrayToArrayExistingLargerSizedTarget() { ScientistDto[] existingTarget = @@ -138,101 +229,108 @@ public void shouldMapArrayToArrayExistingLargerSizedTarget() { assertThat( target ).extracting( "name" ).containsOnly( "Bob", "Larry", "John" ); } - @Test - public void shouldMapTargetToNullWhenNullSource() { - // TODO: What about existing target? + @ProcessorTest + public void shouldReturnMapTargetWhenNullSource() { ScientistDto[] existingTarget = new ScientistDto[]{ new ScientistDto( "Jim" ) }; ScientistDto[] target = ScienceMapper.INSTANCE.scientistsToDtos( null, existingTarget ); - assertThat( target ).isNull(); + assertThat( target ).isNotNull(); + assertThat( target ).isEqualTo( existingTarget ); assertThat( existingTarget ).extracting( "name" ).containsOnly( "Jim" ); } @IssueKey("534") - @Test - public void shouldMapbooleanWhenReturnDefault() { + @ProcessorTest + public void shouldMapBooleanWhenReturnDefault() { boolean[] existingTarget = new boolean[]{true}; boolean[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); assertThat( target ).containsOnly( false ); + assertThat( target ).isEqualTo( existingTarget ); assertThat( existingTarget ).containsOnly( false ); assertThat( ScienceMapper.INSTANCE.nvmMapping( null ) ).isEmpty(); } - @Test - public void shouldMapshortWhenReturnDefault() { + @ProcessorTest + public void shouldMapShortWhenReturnDefault() { short[] existingTarget = new short[]{ 5 }; short[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); assertThat( target ).containsOnly( new short[] { 0 } ); + assertThat( target ).isEqualTo( existingTarget ); assertThat( existingTarget ).containsOnly( new short[] { 0 } ); } - @Test - public void shouldMapcharWhenReturnDefault() { + @ProcessorTest + public void shouldMapCharWhenReturnDefault() { char[] existingTarget = new char[]{ 'a' }; char[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); assertThat( target ).containsOnly( new char[] { 0 } ); + assertThat( target ).isEqualTo( existingTarget ); assertThat( existingTarget ).containsOnly( new char[] { 0 } ); } - @Test - public void shouldMapintWhenReturnDefault() { + @ProcessorTest + public void shouldMapIntWhenReturnDefault() { int[] existingTarget = new int[]{ 5 }; int[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); - assertThat( target ).containsOnly( new int[] { 0 } ); - assertThat( existingTarget ).containsOnly( new int[] { 0 } ); + assertThat( target ).containsOnly( 0 ); + assertThat( target ).isEqualTo( existingTarget ); + assertThat( existingTarget ).containsOnly( 0 ); } - @Test - public void shouldMaplongWhenReturnDefault() { + @ProcessorTest + public void shouldMapLongWhenReturnDefault() { long[] existingTarget = new long[]{ 5L }; long[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); - assertThat( target ).containsOnly( new long[] { 0L } ); - assertThat( existingTarget ).containsOnly( new long[] { 0L } ); + assertThat( target ).containsOnly( 0L ); + assertThat( target ).isEqualTo( existingTarget ); + assertThat( existingTarget ).containsOnly( 0L ); } - @Test - public void shouldMapfloatWhenReturnDefault() { + @ProcessorTest + public void shouldMapFloatWhenReturnDefault() { float[] existingTarget = new float[]{ 3.1f }; float[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); - assertThat( target ).containsOnly( new float[] { 0.0f } ); - assertThat( existingTarget ).containsOnly( new float[] { 0.0f } ); + assertThat( target ).containsOnly( 0.0f ); + assertThat( target ).isEqualTo( existingTarget ); + assertThat( existingTarget ).containsOnly( 0.0f ); } - @Test - public void shouldMapdoubleWhenReturnDefault() { + @ProcessorTest + public void shouldMapDoubleWhenReturnDefault() { double[] existingTarget = new double[]{ 5.0d }; double[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); - assertThat( target ).containsOnly( new double[] { 0.0d } ); - assertThat( existingTarget ).containsOnly( new double[] { 0.0d } ); + assertThat( target ).containsOnly( 0.0d ); + assertThat( target ).isEqualTo( existingTarget ); + assertThat( existingTarget ).containsOnly( 0.0d ); } - @Test - public void shouldVoidMapintWhenReturnNull() { + @ProcessorTest + public void shouldVoidMapIntWhenReturnNull() { long[] existingTarget = new long[]{ 5L }; ScienceMapper.INSTANCE.nvmMappingVoidReturnNull( null, existingTarget ); - assertThat( existingTarget ).containsOnly( new long[] { 5L } ); + assertThat( existingTarget ).containsOnly( 5L ); } - @Test - public void shouldVoidMapintWhenReturnDefault() { + @ProcessorTest + public void shouldVoidMapIntWhenReturnDefault() { long[] existingTarget = new long[]{ 5L }; ScienceMapper.INSTANCE.nvmMappingVoidReturnDefault( null, existingTarget ); - assertThat( existingTarget ).containsOnly( new long[] { 0L } ); + assertThat( existingTarget ).containsOnly( 0L ); } - @Test + @ProcessorTest @IssueKey( "999" ) public void shouldNotContainFQNForStringArray() { generatedSource.forMapper( ScienceMapper.class ).content().doesNotContain( "java.lang.String[]" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/array/ScienceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/array/ScienceMapper.java index 89dbb34021..125dc94c9f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/array/ScienceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/array/ScienceMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.array; @@ -24,7 +11,9 @@ import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ap.test.array._target.GenericScientistDto; import org.mapstruct.ap.test.array._target.ScientistDto; +import org.mapstruct.ap.test.array.source.GenericScientist; import org.mapstruct.ap.test.array.source.Scientist; import org.mapstruct.factory.Mappers; @@ -35,14 +24,37 @@ public interface ScienceMapper { ScientistDto scientistToDto(Scientist scientist); - ScientistDto[] scientistsToDtos(Scientist[] scientists); + ScientistDto[] scientistsToDtosReturnNull(Scientist[] scientists); - ScientistDto[] scientistsToDtos(List scientists); + ScientistDto[] scientistsToDtosReturnNull(List scientists); - List scientistsToDtosAsList(Scientist[] scientists); + List scientistsToDtosAsListReturnNull(Scientist[] scientists); ScientistDto[] scientistsToDtos(Scientist[] scientists, @MappingTarget ScientistDto[] target); + @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT ) + ScientistDto[] scientistsToDtosReturnDefault(Scientist[] scientists); + + @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT ) + ScientistDto[] scientistsToDtosReturnDefault(List scientists); + + @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT ) + List scientistsToDtosAsListReturnDefault(Scientist[] scientists); + + GenericScientistDto genericScientistToDto(GenericScientist scientist); + + GenericScientistDto[] genericScientistToDtosReturnNull(GenericScientist[] genericScientists); + + GenericScientistDto[] genericScientistToDtosReturnNull(List> genericScientists); + + List> genericScientistToDtosAsList(GenericScientist[] genericScientists); + + @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT ) + GenericScientistDto[] genericScientistToDtosReturnDefault(GenericScientist[] genericScientists); + + @IterableMapping( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT ) + GenericScientistDto[] genericScientistToDtosReturnDefault(List> genericScientists); + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) boolean[] nvmMapping(boolean[] source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/array/_target/GenericScientistDto.java b/processor/src/test/java/org/mapstruct/ap/test/array/_target/GenericScientistDto.java new file mode 100644 index 0000000000..ffab268e61 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/array/_target/GenericScientistDto.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.array._target; + +public class GenericScientistDto { + + //CHECKSTYLE:OFF + public T[] publicPublications; + public int[] publicPublicationYears; + //CHECKSTYLE:ON + + private T name; + private T[] publications; + private int[] publicationYears; + + public GenericScientistDto() { + } + + public GenericScientistDto(T name) { + this.name = name; + } + + public T getName() { + return name; + } + + public void setName(T name) { + this.name = name; + } + + public T[] getPublications() { + return publications; + } + + public void setPublications(T[] publications) { + this.publications = publications; + } + + public int[] getPublicationYears() { + return publicationYears; + } + + public void setPublicationYears(int[] publicationYears) { + this.publicationYears = publicationYears; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/array/_target/ScientistDto.java b/processor/src/test/java/org/mapstruct/ap/test/array/_target/ScientistDto.java index 5ff88fbafe..2fe85a14ff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/array/_target/ScientistDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/array/_target/ScientistDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.array._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/array/source/GenericScientist.java b/processor/src/test/java/org/mapstruct/ap/test/array/source/GenericScientist.java new file mode 100644 index 0000000000..6a6f9a8cda --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/array/source/GenericScientist.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.array.source; + +public class GenericScientist { + + //CHECKSTYLE:OFF + public T[] publicPublications; + public T[] publicPublicationYears; + //CHECKSTYLE:ON + private T name; + private T[] publications; + private T[] publicationYears; + + public GenericScientist(T name) { + this.name = name; + } + + public T getName() { + return name; + } + + public void setName(T name) { + this.name = name; + } + + public T[] getPublications() { + return publications; + } + + public void setPublications(T[] publications) { + this.publications = publications; + } + + public T[] getPublicationYears() { + return publicationYears; + } + + public void setPublicationYears(T[] publicationYears) { + this.publicationYears = publicationYears; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/array/source/Scientist.java b/processor/src/test/java/org/mapstruct/ap/test/array/source/Scientist.java index 3e88df977e..ac2f01f1d1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/array/source/Scientist.java +++ b/processor/src/test/java/org/mapstruct/ap/test/array/source/Scientist.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.array.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bool/BooleanMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/bool/BooleanMappingTest.java index 01dff441a0..9efb09b1e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bool/BooleanMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bool/BooleanMappingTest.java @@ -1,29 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bool; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Person.class, @@ -32,10 +17,9 @@ PersonMapper.class, YesNoMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class BooleanMappingTest { - @Test + @ProcessorTest public void shouldMapBooleanPropertyWithIsPrefixedGetter() { //given Person person = new Person(); @@ -48,7 +32,7 @@ public void shouldMapBooleanPropertyWithIsPrefixedGetter() { assertThat( personDto.getMarried() ).isEqualTo( "true" ); } - @Test + @ProcessorTest public void shouldMapBooleanPropertyPreferringGetPrefixedGetterOverIsPrefixedGetter() { //given Person person = new Person(); @@ -61,7 +45,7 @@ public void shouldMapBooleanPropertyPreferringGetPrefixedGetterOverIsPrefixedGet assertThat( personDto.getEngaged() ).isEqualTo( "true" ); } - @Test + @ProcessorTest public void shouldMapBooleanPropertyWithPropertyMappingMethod() { // given Person person = new Person(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bool/Person.java b/processor/src/test/java/org/mapstruct/ap/test/bool/Person.java index 939b776bb7..6b20598ea4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bool/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bool/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bool; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bool/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/bool/PersonDto.java index 07c10c29aa..6240df6860 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bool/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bool/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bool; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bool/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bool/PersonMapper.java index f064f38534..04f806b11f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bool/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bool/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bool; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bool/YesNo.java b/processor/src/test/java/org/mapstruct/ap/test/bool/YesNo.java index 8a087961ff..7bbdb67cd4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bool/YesNo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bool/YesNo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bool; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bool/YesNoMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bool/YesNoMapper.java index 79616caf19..5cc1a4c78f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bool/YesNoMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bool/YesNoMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bool; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/AbstractEntity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/AbstractEntity.java index 7bd16b45a4..88eaeffbb3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/AbstractEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/AbstractEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasKey.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasKey.java index 6f130710d7..e8c9b71ef9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasKey.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasKey.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasPrimaryKey.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasPrimaryKey.java index f507ba52cf..a027a51cbd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasPrimaryKey.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/HasPrimaryKey.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractResultTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractResultTypeMapper.java index fa8658189d..b44b4e1476 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractResultTypeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractResultTypeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractReturnTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractReturnTypeMapper.java index 48a6069a89..a71a4d1417 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractReturnTypeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousAbstractReturnTypeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceResultTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceResultTypeMapper.java index 0c61c60163..b84821dc86 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceResultTypeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceResultTypeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceReturnTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceReturnTypeMapper.java index 01007b6579..525dc8ee94 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceReturnTypeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005ErroneousInterfaceReturnTypeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005Test.java index 2aac9adfe1..5198394eb1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Issue1005Test.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov */ @IssueKey("1005") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ AbstractEntity.class, HasKey.class, @@ -42,52 +26,52 @@ public class Issue1005Test { @WithClasses(Issue1005ErroneousAbstractResultTypeMapper.class) - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Issue1005ErroneousAbstractResultTypeMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 30, - messageRegExp = "The result type .*\\.AbstractEntity may not be an abstract class nor interface.") + line = 17, + message = "The result type AbstractEntity may not be an abstract class nor interface.") }) - public void shouldFailDueToAbstractResultType() throws Exception { + public void shouldFailDueToAbstractResultType() { } @WithClasses(Issue1005ErroneousAbstractReturnTypeMapper.class) - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Issue1005ErroneousAbstractReturnTypeMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "The return type .*\\.AbstractEntity is an abstract class or interface. Provide a non" + - " abstract / non interface result type or a factory method.") + line = 16, + message = "The return type AbstractEntity is an abstract class or interface. " + + "Provide a non abstract / non interface result type or a factory method.") }) - public void shouldFailDueToAbstractReturnType() throws Exception { + public void shouldFailDueToAbstractReturnType() { } @WithClasses(Issue1005ErroneousInterfaceResultTypeMapper.class) - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Issue1005ErroneousInterfaceResultTypeMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 30, - messageRegExp = "The result type .*\\.HasPrimaryKey may not be an abstract class nor interface.") + line = 17, + message = "The result type HasPrimaryKey may not be an abstract class nor interface.") }) - public void shouldFailDueToInterfaceResultType() throws Exception { + public void shouldFailDueToInterfaceResultType() { } @WithClasses(Issue1005ErroneousInterfaceReturnTypeMapper.class) - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Issue1005ErroneousInterfaceReturnTypeMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "The return type .*\\.HasKey is an abstract class or interface. Provide a non " + - "abstract / non interface result type or a factory method.") + line = 16, + message = "The return type HasKey is an abstract class or interface. " + + "Provide a non abstract / non interface result type or a factory method.") }) - public void shouldFailDueToInterfaceReturnType() throws Exception { + public void shouldFailDueToInterfaceReturnType() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Order.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Order.java index 8086328965..e9722e13ce 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Order.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/Order.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/OrderDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/OrderDto.java index 7dcdb85fd7..5108bd07de 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/OrderDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1005/OrderDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1005; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/ErroneousIssue1029Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/ErroneousIssue1029Mapper.java index b9ccfdc463..65cc635043 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/ErroneousIssue1029Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/ErroneousIssue1029Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1029; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/Issue1029Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/Issue1029Test.java index 93832bb68e..c2a87b769a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/Issue1029Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1029/Issue1029Test.java @@ -1,53 +1,37 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1029; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Verifies that read-only properties can be explicitly mentioned as {@code ignored=true} without raising an error. * * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(ErroneousIssue1029Mapper.class) @IssueKey("1029") public class Issue1029Test { - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(kind = Kind.WARNING, line = 39, type = ErroneousIssue1029Mapper.class, - messageRegExp = "Unmapped target properties: \"knownProp, lastUpdated, computedMapping\"\\."), - @Diagnostic(kind = Kind.WARNING, line = 50, type = ErroneousIssue1029Mapper.class, - messageRegExp = "Unmapped target property: \"lastUpdated\"\\."), - @Diagnostic(kind = Kind.ERROR, line = 55, type = ErroneousIssue1029Mapper.class, - messageRegExp = "Unknown property \"unknownProp\" in result type " + - "org.mapstruct.ap.test.bugs._1029.ErroneousIssue1029Mapper.Deck\\. Did you mean \"knownProp\"?") + @Diagnostic(kind = Kind.WARNING, line = 26, type = ErroneousIssue1029Mapper.class, + message = "Unmapped target properties: \"knownProp, lastUpdated, computedMapping\"."), + @Diagnostic(kind = Kind.WARNING, line = 37, type = ErroneousIssue1029Mapper.class, + message = "Unmapped target property: \"lastUpdated\"."), + @Diagnostic(kind = Kind.ERROR, line = 42, type = ErroneousIssue1029Mapper.class, + message = "Unknown property \"unknownProp\" in result type ErroneousIssue1029Mapper.Deck. " + + "Did you mean \"knownProp\"?") }) public void reportsProperWarningsAndError() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/Issue1061Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/Issue1061Test.java index 22d681d8ff..b060d9727f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/Issue1061Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/Issue1061Test.java @@ -1,39 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1061; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov */ @IssueKey("1061") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(SourceTargetMapper.class) public class Issue1061Test { - @Test - public void shouldCompile() throws Exception { + @ProcessorTest + public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/SourceTargetMapper.java index ff677f581e..88bc5328ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1061/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1061; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Mapper.java index 8a81d91ed4..322034d590 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Mapper.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1111; import java.util.List; + import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -37,8 +25,29 @@ public interface Issue1111Mapper { List> listList(List> in); - class Source { } + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } - class Target { } + public String getValue() { + return value; + } + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Test.java index a908491e7c..f5efb21e3a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1111/Issue1111Test.java @@ -1,34 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1111; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; + import org.mapstruct.ap.test.bugs._1111.Issue1111Mapper.Source; import org.mapstruct.ap.test.bugs._1111.Issue1111Mapper.Target; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @@ -36,13 +22,12 @@ */ @IssueKey( "1111") @WithClasses({Issue1111Mapper.class}) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue1111Test { - @Test + @ProcessorTest public void shouldCompile() { - List> source = Arrays.asList( Arrays.asList( new Source() ) ); + List> source = Arrays.asList( Arrays.asList( new Source( "test" ) ) ); List> target = Issue1111Mapper.INSTANCE.listList( source ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Mapper.java index 940d78cfee..cae987aabe 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1124; @@ -72,6 +59,6 @@ public void setEntity(DTO entity) { class MappingContext { } - @Mapping(source = "entity.id", target = "id") + @Mapping(target = "id", source = "entity.id") DTO map(Entity entity, @Context MappingContext context); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Test.java index ef2ddc9143..aecc0a3a15 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1124/Issue1124Test.java @@ -1,43 +1,27 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1124; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._1124.Issue1124Mapper.DTO; import org.mapstruct.ap.test.bugs._1124.Issue1124Mapper.Entity; import org.mapstruct.ap.test.bugs._1124.Issue1124Mapper.MappingContext; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Andreas Gudian */ @IssueKey("1124") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(Issue1124Mapper.class) public class Issue1124Test { - @Test + @ProcessorTest public void nestedPropertyWithContextCompiles() { Entity entity = new Entity(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Mapper.java index 0746671992..350d95eebc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1130; @@ -43,6 +30,16 @@ public void setB(BEntity b) { } static class BEntity { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } } static class ADto { @@ -59,6 +56,7 @@ public void setB(BDto b) { class BDto { private final String passedViaConstructor; + private String id; BDto(String passedViaConstructor) { this.passedViaConstructor = passedViaConstructor; @@ -67,6 +65,14 @@ class BDto { String getPassedViaConstructor() { return passedViaConstructor; } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } } abstract void mergeA(AEntity source, @MappingTarget ADto target); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Test.java index fd0027b42d..d0f8a1d3a4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1130/Issue1130Test.java @@ -1,36 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1130; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.TargetType; import org.mapstruct.ap.test.bugs._1130.Issue1130Mapper.ADto; import org.mapstruct.ap.test.bugs._1130.Issue1130Mapper.AEntity; import org.mapstruct.ap.test.bugs._1130.Issue1130Mapper.BEntity; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests that when calling an update method for a previously null property, the factory method is called even if that * factory method has a {@link TargetType} annotation. @@ -38,10 +23,9 @@ * @author Andreas Gudian */ @IssueKey("1130") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(Issue1130Mapper.class) public class Issue1130Test { - @Test + @ProcessorTest public void factoryMethodWithTargetTypeInUpdateMethods() { AEntity aEntity = new AEntity(); aEntity.setB( new BEntity() ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Mapper.java index 5059ffe6ce..0e82c0708b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1131; @@ -33,7 +20,7 @@ public abstract class Issue1131Mapper { public static final Issue1131Mapper INSTANCE = Mappers.getMapper( Issue1131Mapper.class ); - public static final List CALLED_METHODS = new ArrayList(); + public static final List CALLED_METHODS = new ArrayList<>(); public abstract void merge(Source source, @MappingTarget Target target); @@ -53,7 +40,7 @@ protected Target.Nested createWithSource(Source source) { @ObjectFactory protected List createWithSourceList(List source) { CALLED_METHODS.add( "create(List)" ); - List result = new ArrayList(); + List result = new ArrayList<>(); result.add( new Target.Nested( "from createWithSourceList" ) ); return result; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131MapperWithContext.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131MapperWithContext.java index c75a967756..3f3176b57a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131MapperWithContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131MapperWithContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1131; @@ -35,7 +22,7 @@ public abstract class Issue1131MapperWithContext { public static final Issue1131MapperWithContext INSTANCE = Mappers.getMapper( Issue1131MapperWithContext.class ); public static class MappingContext { - private final List calledMethods = new ArrayList(); + private final List calledMethods = new ArrayList<>(); public Target.Nested create(Source.Nested source) { calledMethods.add( "create(Source.Nested)" ); @@ -45,10 +32,10 @@ public Target.Nested create(Source.Nested source) { public List create(List source) { calledMethods.add( "create(List)" ); if ( source == null ) { - return new ArrayList(); + return new ArrayList<>(); } else { - return new ArrayList( source.size() ); + return new ArrayList<>( source.size() ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Test.java index 3f1d167769..7a8c2797d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Issue1131Test.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1131; import java.util.ArrayList; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1131") @WithClasses({ Issue1131Mapper.class, @@ -41,16 +25,17 @@ }) public class Issue1131Test { - @Test + @ProcessorTest public void shouldUseCreateWithSourceNested() { Source source = new Source(); source.setNested( new Source.Nested() ); source.getNested().setProperty( "something" ); - source.setMoreNested( new ArrayList() ); + source.setMoreNested( new ArrayList<>() ); Target target = new Target(); + Issue1131Mapper.CALLED_METHODS.clear(); Issue1131Mapper.INSTANCE.merge( source, target ); assertThat( target.getNested() ).isNotNull(); @@ -62,13 +47,13 @@ public void shouldUseCreateWithSourceNested() { ); } - @Test + @ProcessorTest public void shouldUseContextObjectFactory() { Source source = new Source(); source.setNested( new Source.Nested() ); source.getNested().setProperty( "something" ); - source.setMoreNested( new ArrayList() ); + source.setMoreNested( new ArrayList<>() ); Target target = new Target(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Source.java index fef5f8d435..38c5e28490 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1131; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Target.java index d97617950d..a0a6337bc0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1131/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1131; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Entity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Entity.java index 6ed4f1e48b..2db0196cf5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Entity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Entity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1148; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Mapper.java index f4ae218ca1..cf2cfdfaf4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1148; @@ -32,26 +19,26 @@ public interface Issue1148Mapper { Issue1148Mapper INSTANCE = Mappers.getMapper( Issue1148Mapper.class ); @Mappings({ - @Mapping(source = "senderId", target = "sender.nestedClient.id"), - @Mapping(source = "recipientId", target = "recipient.nestedClient.id"), - @Mapping(source = "sameLevel.client.id", target = "client.nestedClient.id"), - @Mapping(source = "sameLevel2.client.id", target = "client2.nestedClient.id"), - @Mapping(source = "level.client.id", target = "nested.id"), - @Mapping(source = "level2.client.id", target = "nested2.id"), - @Mapping(source = "nestedDto.id", target = "id"), - @Mapping(source = "nestedDto2.id", target = "id2") + @Mapping(target = "sender.nestedClient.id", source = "senderId"), + @Mapping(target = "recipient.nestedClient.id", source = "recipientId"), + @Mapping(target = "client.nestedClient.id", source = "sameLevel.client.id"), + @Mapping(target = "client2.nestedClient.id", source = "sameLevel2.client.id"), + @Mapping(target = "nested.id", source = "level.client.id"), + @Mapping(target = "nested2.id", source = "level2.client.id"), + @Mapping(target = "id", source = "nestedDto.id"), + @Mapping(target = "id2", source = "nestedDto2.id") }) Entity toEntity(Entity.Dto dto); @Mappings({ - @Mapping(source = "dto2.senderId", target = "sender.nestedClient.id"), - @Mapping(source = "dto1.recipientId", target = "recipient.nestedClient.id"), - @Mapping(source = "dto1.sameLevel.client.id", target = "client.nestedClient.id"), - @Mapping(source = "dto2.sameLevel2.client.id", target = "client2.nestedClient.id"), - @Mapping(source = "dto1.level.client.id", target = "nested.id"), - @Mapping(source = "dto2.level2.client.id", target = "nested2.id"), - @Mapping(source = "dto1.nestedDto.id", target = "id"), - @Mapping(source = "dto2.nestedDto2.id", target = "id2") + @Mapping(target = "sender.nestedClient.id", source = "dto2.senderId"), + @Mapping(target = "recipient.nestedClient.id", source = "dto1.recipientId"), + @Mapping(target = "client.nestedClient.id", source = "dto1.sameLevel.client.id"), + @Mapping(target = "client2.nestedClient.id", source = "dto2.sameLevel2.client.id"), + @Mapping(target = "nested.id", source = "dto1.level.client.id"), + @Mapping(target = "nested2.id", source = "dto2.level2.client.id"), + @Mapping(target = "id", source = "dto1.nestedDto.id"), + @Mapping(target = "id2", source = "dto2.nestedDto2.id") }) Entity toEntity(Entity.Dto dto1, Entity.Dto dto2); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Test.java index 5997b93d66..a698cfbfc6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1148/Issue1148Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1148; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -33,12 +18,11 @@ Entity.class, Issue1148Mapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1148") public class Issue1148Test { - @Test - public void shouldNotUseSameMethodForDifferentMappingsNestedSource() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsNestedSource() { Entity.Dto dto = new Entity.Dto(); dto.nestedDto = new Entity.NestedDto( 30 ); dto.nestedDto2 = new Entity.NestedDto( 40 ); @@ -48,8 +32,8 @@ public void shouldNotUseSameMethodForDifferentMappingsNestedSource() throws Exce assertThat( entity.getId2() ).isEqualTo( 40 ); } - @Test - public void shouldNotUseSameMethodForDifferentMappingsNestedTarget() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsNestedTarget() { Entity.Dto dto = new Entity.Dto(); dto.recipientId = 10; dto.senderId = 20; @@ -64,8 +48,8 @@ public void shouldNotUseSameMethodForDifferentMappingsNestedTarget() throws Exce assertThat( entity.getSender().nestedClient.id ).isEqualTo( 20 ); } - @Test - public void shouldNotUseSameMethodForDifferentMappingsSymmetric() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsSymmetric() { Entity.Dto dto = new Entity.Dto(); dto.sameLevel = new Entity.ClientDto(new Entity.NestedDto( 30 )); dto.sameLevel2 = new Entity.ClientDto(new Entity.NestedDto( 40 )); @@ -80,8 +64,8 @@ public void shouldNotUseSameMethodForDifferentMappingsSymmetric() throws Excepti assertThat( entity.client2.nestedClient.id ).isEqualTo( 40 ); } - @Test - public void shouldNotUseSameMethodForDifferentMappingsHalfSymmetric() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsHalfSymmetric() { Entity.Dto dto = new Entity.Dto(); dto.level = new Entity.ClientDto(new Entity.NestedDto( 80 )); dto.level2 = new Entity.ClientDto(new Entity.NestedDto( 90 )); @@ -94,8 +78,8 @@ public void shouldNotUseSameMethodForDifferentMappingsHalfSymmetric() throws Exc assertThat( entity.nested2.id ).isEqualTo( 90 ); } - @Test - public void shouldNotUseSameMethodForDifferentMappingsNestedSourceMultiple() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsNestedSourceMultiple() { Entity.Dto dto1 = new Entity.Dto(); dto1.nestedDto = new Entity.NestedDto( 30 ); Entity.Dto dto2 = new Entity.Dto(); @@ -106,8 +90,8 @@ public void shouldNotUseSameMethodForDifferentMappingsNestedSourceMultiple() thr assertThat( entity.getId2() ).isEqualTo( 40 ); } - @Test - public void shouldNotUseSameMethodForDifferentMappingsNestedTargetMultiple() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsNestedTargetMultiple() { Entity.Dto dto1 = new Entity.Dto(); dto1.recipientId = 10; Entity.Dto dto2 = new Entity.Dto(); @@ -123,8 +107,8 @@ public void shouldNotUseSameMethodForDifferentMappingsNestedTargetMultiple() thr assertThat( entity.getSender().nestedClient.id ).isEqualTo( 20 ); } - @Test - public void shouldNotUseSameMethodForDifferentMappingsSymmetricMultiple() throws Exception { + @ProcessorTest + public void shouldNotUseSameMethodForDifferentMappingsSymmetricMultiple() { Entity.Dto dto1 = new Entity.Dto(); dto1.sameLevel = new Entity.ClientDto(new Entity.NestedDto( 30 )); Entity.Dto dto2 = new Entity.Dto(); @@ -140,7 +124,7 @@ public void shouldNotUseSameMethodForDifferentMappingsSymmetricMultiple() throws assertThat( entity.client2.nestedClient.id ).isEqualTo( 40 ); } - @Test + @ProcessorTest public void shouldNotUseSameMethodForDifferentMappingsHalfSymmetricMultiple() { Entity.Dto dto1 = new Entity.Dto(); dto1.level = new Entity.ClientDto(new Entity.NestedDto( 80 )); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/ErroneousIssue1153Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/ErroneousIssue1153Mapper.java index 67f87bcf9f..71c8998a79 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/ErroneousIssue1153Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/ErroneousIssue1153Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1153; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/Issue1153Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/Issue1153Test.java index e28eeb59b3..5ceb1bb715 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/Issue1153Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1153/Issue1153Test.java @@ -1,36 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1153; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(ErroneousIssue1153Mapper.class) @IssueKey("1153") public class Issue1153Test { @@ -39,22 +23,21 @@ public class Issue1153Test { diagnostics = { @Diagnostic(type = ErroneousIssue1153Mapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = "Property \"readOnly\" has no write accessor in " + - "org.mapstruct.ap.test.bugs._1153.ErroneousIssue1153Mapper.Target\\."), + line = 19, + message = "Property \"readOnly\" has no write accessor in ErroneousIssue1153Mapper.Target."), @Diagnostic(type = ErroneousIssue1153Mapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Property \"nestedTarget.readOnly\" has no write accessor in " + - "org.mapstruct.ap.test.bugs._1153.ErroneousIssue1153Mapper.Target\\."), + line = 20, + message = + "Property \"readOnly\" has no write accessor in ErroneousIssue1153Mapper.Target.NestedTarget " + + "for target name \"nestedTarget.readOnly\"."), @Diagnostic(type = ErroneousIssue1153Mapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 36, - messageRegExp = "Unknown property \"nestedTarget2.writable2\" in result type " + - "org.mapstruct.ap.test.bugs._1153.ErroneousIssue1153Mapper.Target\\. " + - "Did you mean \"nestedTarget2\\.writable\"") + line = 23, + message = "Unknown property \"writable2\" in type ErroneousIssue1153Mapper.Target.NestedTarget " + + "for target name \"nestedTarget2.writable2\". Did you mean \"nestedTarget2.writable\"?") }) - @Test + @ProcessorTest public void shouldReportErrorsCorrectly() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Entity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Entity.java index 62a2394350..08617d6462 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Entity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Entity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1155; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Mapper.java index 5db16bd460..072121bf79 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1155; @@ -30,6 +17,6 @@ public interface Issue1155Mapper { Issue1155Mapper INSTANCE = Mappers.getMapper( Issue1155Mapper.class ); - @Mapping(source = "clientId", target = "client.id") + @Mapping(target = "client.id", source = "clientId") Entity toEntity(Entity.Dto dto); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Test.java index 730c81b7e8..9a6bb40ed1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1155/Issue1155Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1155; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -33,12 +18,11 @@ Entity.class, Issue1155Mapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1155") public class Issue1155Test { - @Test - public void shouldCompile() throws Exception { + @ProcessorTest + public void shouldCompile() { Entity.Dto dto = new Entity.Dto(); dto.clientId = 10; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/FaultyAstModifyingAnnotationProcessor.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/FaultyAstModifyingAnnotationProcessor.java new file mode 100644 index 0000000000..99d88e9883 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/FaultyAstModifyingAnnotationProcessor.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1159; + +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; + +/** + * @author Filip Hrisafov + */ +public class FaultyAstModifyingAnnotationProcessor implements AstModifyingAnnotationProcessor { + + public FaultyAstModifyingAnnotationProcessor() { + throw new RuntimeException( "Faulty AstModifyingAnnotationProcessor should not be instantiated" ); + } + + @Override + public boolean isTypeComplete(TypeMirror type) { + return false; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/Issue1159Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/Issue1159Mapper.java new file mode 100644 index 0000000000..ab1441c142 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/Issue1159Mapper.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1159; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1159Mapper { + + Issue1159Mapper INSTANCE = Mappers.getMapper( Issue1159Mapper.class ); + + CarManualDto translateManual(CarManual manual); + + /** + * @author Filip Hrisafov + */ + class CarManual { + + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } + + /** + * @author Filip Hrisafov + */ + class CarManualDto { + + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/Issue1159Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/Issue1159Test.java new file mode 100644 index 0000000000..7740662632 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1159/Issue1159Test.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1159; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.Compiler; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1159") +@WithClasses({ + Issue1159Mapper.class, +}) +@WithServiceImplementation( + provides = AstModifyingAnnotationProcessor.class, + value = FaultyAstModifyingAnnotationProcessor.class +) +public class Issue1159Test { + + @ProcessorTest(Compiler.JDK) + // The warning is not present in the Eclipse compilation for some reason + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + messageRegExp = "Failed to read AstModifyingAnnotationProcessor. Reading next processor. Reason:.*" + + "Faulty AstModifyingAnnotationProcessor should not be instantiated" + ) + }) + public void shouldIgnoreFaultyAstModifyingProcessor() { + + Issue1159Mapper.CarManual manual = new Issue1159Mapper.CarManual(); + manual.setContent( "test" ); + + Issue1159Mapper.CarManualDto manualDto = Issue1159Mapper.INSTANCE.translateManual( manual ); + + assertThat( manualDto ).isNotNull(); + assertThat( manualDto.getContent() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/GenericHolder.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/GenericHolder.java index 7d5dd28d6b..6ebf510872 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/GenericHolder.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/GenericHolder.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1164; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Issue1164Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Issue1164Test.java index fd2990b1b7..6db73113b6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Issue1164Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Issue1164Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1164; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -33,11 +18,10 @@ GenericHolder.class, SourceTargetMapper.class } ) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey( "1164" ) public class Issue1164Test { - @Test + @ProcessorTest public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Source.java index e59304c77d..7f72633739 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1164; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/SourceTargetMapper.java index 9761dfa015..31cb10ba6f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1164; @@ -34,14 +21,14 @@ public abstract class SourceTargetMapper { public abstract Target map(Source source); protected List> mapLists(List> lists) { - return new ArrayList>(); + return new ArrayList<>(); } protected Map> map(Map> map) { - return new HashMap>(); + return new HashMap<>(); } protected GenericHolder> map(GenericHolder> genericHolder) { - return new GenericHolder>(); + return new GenericHolder<>(); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Target.java index c80a8ecc22..103a699a1f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1164/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1164; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderSourceTargetMapper.java index a966299759..e882421e9d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderSourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1170; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderTest.java index 90b19f92e0..88576ba711 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/AdderTest.java @@ -1,34 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1170; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.assertj.core.api.ListAssert; import org.mapstruct.ap.test.bugs._1170._target.Target; import org.mapstruct.ap.test.bugs._1170.source.Source; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Cornelius Dirmeier @@ -39,11 +25,10 @@ AdderSourceTargetMapper.class, PetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class AdderTest { @IssueKey("1170") - @Test + @ProcessorTest public void testWildcardAdder() { Source source = new Source(); source.addWithoutWildcard( "mouse" ); @@ -57,13 +42,13 @@ public void testWildcardAdder() { assertThat( target ).isNotNull(); assertThat( target.getWithoutWildcards() ).containsExactly( 2L ); assertThat( target.getWildcardInSources() ).containsExactly( 2L ); - assertThat( target.getWildcardInTargets() ).containsExactly( 2L ); - assertThat( target.getWildcardInBoths() ).containsExactly( 2L ); + ( (ListAssert) assertThat( target.getWildcardInTargets() ) ).containsExactly( 2L ); + ( (ListAssert) assertThat( target.getWildcardInBoths() ) ).containsExactly( 2L ); assertThat( target.getWildcardAdderToSetters() ).containsExactly( 2L ); } @IssueKey("1170") - @Test + @ProcessorTest public void testWildcardAdderTargetToSource() { Target target = new Target(); target.addWithoutWildcard( 2L ); @@ -76,10 +61,9 @@ public void testWildcardAdderTargetToSource() { assertThat( source ).isNotNull(); assertThat( source.getWithoutWildcards() ).containsExactly( "mouse" ); - assertThat( source.getWildcardInSources() ).containsExactly( "mouse" ); + ( (ListAssert) assertThat( source.getWildcardInSources() ) ).containsExactly( "mouse" ); assertThat( source.getWildcardInTargets() ).containsExactly( "mouse" ); - assertThat( source.getWildcardInBoths() ).containsExactly( "mouse" ); - assertThat( source.getWildcardAdderToSetters() ).containsExactly( "mouse" ); + ( (ListAssert) assertThat( source.getWildcardInBoths() ) ).containsExactly( "mouse" ); + ( (ListAssert) assertThat( source.getWildcardAdderToSetters() ) ).containsExactly( "mouse" ); } - } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/PetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/PetMapper.java index 847ec04245..10acf7f9c5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/PetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/PetMapper.java @@ -1,30 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1170; -import java.util.ArrayList; import java.util.List; import java.util.Map; - -import org.mapstruct.Mapper; +import java.util.stream.Collectors; import com.google.common.collect.ImmutableMap; +import org.mapstruct.Mapper; /** * @author Cornelius Dirmeier @@ -42,15 +28,12 @@ public class PetMapper { .put( 3L, "cat" ) .put( 4L, "dog" ).build(); - /** * method to be used when using an adder * * @param pet * * @return - * - * @throws DogException */ public Long toPet(String pet) { return PETS_TO_TARGET.get( pet ); @@ -66,24 +49,17 @@ public String toSourcePets(Long pet) { * @param pets * * @return - * - * @throws CatException - * @throws DogException */ public List toPets(List pets) { - List result = new ArrayList(); - for ( String pet : pets ) { - result.add( toPet( pet ) ); - } - return result; + return pets.stream() + .map( this::toPet ) + .collect( Collectors.toList() ); } public List toSourcePets(List pets) { - List result = new ArrayList(); - for ( Long pet : pets ) { - result.add( PETS_TO_SOURCE.get( pet ) ); - } - return result; + return pets.stream() + .map( PETS_TO_SOURCE::get ) + .collect( Collectors.toList() ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/_target/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/_target/Target.java index 4e57ce7ff5..5103fb075a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/_target/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/_target/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1170._target; @@ -27,23 +14,23 @@ */ public class Target { - private List withoutWildcards = new ArrayList(); + private List withoutWildcards = new ArrayList<>(); - private List wildcardInSources = new ArrayList(); + private List wildcardInSources = new ArrayList<>(); - private List wildcardInTargets = new ArrayList(); + private List wildcardInTargets = new ArrayList<>(); - private List wildcardInBoths = new ArrayList(); + private List wildcardInBoths = new ArrayList<>(); - private List wildcardAdderToSetters = new ArrayList(); + private List wildcardAdderToSetters = new ArrayList<>(); - private List wildcardInSourcesAddAll = new ArrayList(); + private List wildcardInSourcesAddAll = new ArrayList<>(); - private List sameTypeWildcardInSources = new ArrayList(); + private List sameTypeWildcardInSources = new ArrayList<>(); - private List sameTypeWildcardInTargets = new ArrayList(); + private List sameTypeWildcardInTargets = new ArrayList<>(); - private List sameTypeWildcardInBoths = new ArrayList(); + private List sameTypeWildcardInBoths = new ArrayList<>(); public List getWithoutWildcards() { return withoutWildcards; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/source/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/source/Source.java index 07c5d671bc..989ef5f6b9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/source/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1170/source/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1170.source; @@ -27,23 +14,23 @@ */ public class Source { - private List withoutWildcards = new ArrayList(); + private List withoutWildcards = new ArrayList<>(); - private List wildcardInSources = new ArrayList(); + private List wildcardInSources = new ArrayList<>(); - private List wildcardInTargets = new ArrayList(); + private List wildcardInTargets = new ArrayList<>(); - private List wildcardInBoths = new ArrayList(); + private List wildcardInBoths = new ArrayList<>(); - private List wildcardInSourcesAddAll = new ArrayList(); + private List wildcardInSourcesAddAll = new ArrayList<>(); - private List wildcardAdderToSetters = new ArrayList(); + private List wildcardAdderToSetters = new ArrayList<>(); - private List sameTypeWildcardInSources = new ArrayList(); + private List sameTypeWildcardInSources = new ArrayList<>(); - private List sameTypeWildcardInTargets = new ArrayList(); + private List sameTypeWildcardInTargets = new ArrayList<>(); - private List sameTypeWildcardInBoths = new ArrayList(); + private List sameTypeWildcardInBoths = new ArrayList<>(); public List getWithoutWildcards() { return withoutWildcards; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/ErroneousIssue1180Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/ErroneousIssue1180Mapper.java index be815188c8..1f22d34578 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/ErroneousIssue1180Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/ErroneousIssue1180Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1180; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Issue1180Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Issue1180Test.java index 3953d6950d..865816d83e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Issue1180Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Issue1180Test.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1180; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Sjaak Derksen @@ -36,16 +21,15 @@ SharedConfig.class, ErroneousIssue1180Mapper.class } ) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey( "1180" ) public class Issue1180Test { - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = SharedConfig.class, + @Diagnostic(type = ErroneousIssue1180Mapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, + line = 18, messageRegExp = "No property named \"sourceProperty\\.nonExistant\" exists.*") }) public void shouldCompileButNotGiveNullPointer() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/SharedConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/SharedConfig.java index a0dc7f6291..3afa895967 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/SharedConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/SharedConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1180; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Source.java index f8d57efb9e..5f21a327f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1180; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Target.java index 8948548f49..5619562567 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1180/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1180; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/Issue1215Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/Issue1215Test.java index 1e4255eb0a..e3c08488a0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/Issue1215Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/Issue1215Test.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1215; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._1215.dto.EntityDTO; import org.mapstruct.ap.test.bugs._1215.entity.AnotherTag; import org.mapstruct.ap.test.bugs._1215.entity.Entity; import org.mapstruct.ap.test.bugs._1215.entity.Tag; import org.mapstruct.ap.test.bugs._1215.mapper.Issue1215Mapper; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -40,10 +25,9 @@ Issue1215Mapper.class } ) @IssueKey( "1215" ) -@RunWith( AnnotationProcessorTestRunner.class ) public class Issue1215Test { - @Test + @ProcessorTest public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/dto/EntityDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/dto/EntityDTO.java index 364dda4b12..68267dd30e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/dto/EntityDTO.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/dto/EntityDTO.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1215.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/AnotherTag.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/AnotherTag.java index 16f454567b..0938b1a783 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/AnotherTag.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/AnotherTag.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1215.entity; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Entity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Entity.java index e6e9a170f8..37ae4e1038 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Entity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Entity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1215.entity; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Tag.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Tag.java index b5962fee1d..04729f35b5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Tag.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/entity/Tag.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1215.entity; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/mapper/Issue1215Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/mapper/Issue1215Mapper.java index da517a25bd..979b6f51c4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/mapper/Issue1215Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1215/mapper/Issue1215Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1215.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Mapper.java index 443cf12f1e..e34174f27b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1227; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Test.java index cf9231a71e..f98f6de398 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/Issue1227Test.java @@ -1,41 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1227; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov */ @IssueKey("1227") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Issue1227Mapper.class, ThreadDto.class }) public class Issue1227Test { - @Test + @ProcessorTest public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/ThreadDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/ThreadDto.java index f503f3c112..ff14066a72 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/ThreadDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1227/ThreadDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1227; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/ErroneousIssue1242MapperMultipleSources.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/ErroneousIssue1242MapperMultipleSources.java index 3732aca923..7a8ad05542 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/ErroneousIssue1242MapperMultipleSources.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/ErroneousIssue1242MapperMultipleSources.java @@ -1,32 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; import org.mapstruct.Mapper; import org.mapstruct.ObjectFactory; +import org.mapstruct.ReportingPolicy; /** * Results in an ambiguous factory method error, as there are two methods with matching source types available. * * @author Andreas Gudian */ -@Mapper(uses = TargetFactories.class) +@Mapper(uses = TargetFactories.class, unmappedTargetPolicy = ReportingPolicy.IGNORE) public abstract class ErroneousIssue1242MapperMultipleSources { abstract TargetA toTargetA(SourceA source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Mapper.java index 45e7547fdd..90ea60a2ee 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Mapper.java @@ -1,32 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; import org.mapstruct.Mapper; import org.mapstruct.MappingTarget; +import org.mapstruct.ReportingPolicy; /** * Test mapper for properly resolving the best fitting factory method * * @author Andreas Gudian */ -@Mapper(uses = TargetFactories.class) +@Mapper(uses = TargetFactories.class, unmappedTargetPolicy = ReportingPolicy.IGNORE) public abstract class Issue1242Mapper { abstract TargetA toTargetA(SourceA source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Test.java index bf548e0108..036a63f312 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/Issue1242Test.java @@ -1,35 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests that if multiple factory methods are applicable but only one of them has a source parameter, the one with the * source param is chosen. @@ -37,7 +22,6 @@ * @author Andreas Gudian */ @IssueKey("1242") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Issue1242Mapper.class, SourceA.class, @@ -47,7 +31,7 @@ TargetFactories.class }) public class Issue1242Test { - @Test + @ProcessorTest public void factoryMethodWithSourceParamIsChosen() { SourceA sourceA = new SourceA(); sourceA.setB( new SourceB() ); @@ -64,23 +48,19 @@ public void factoryMethodWithSourceParamIsChosen() { assertThat( targetA.getB().getPassedViaConstructor() ).isEqualTo( "created by factory" ); } - @Test + @ProcessorTest @WithClasses(ErroneousIssue1242MapperMultipleSources.class) @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousIssue1242MapperMultipleSources.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Ambiguous factory methods found for creating .*TargetB:" - + " .*TargetB anotherTargetBCreator\\(.*SourceB source\\)," - + " .*TargetB .*TargetFactories\\.createTargetB\\(.*SourceB source," - + " @TargetType .*Class<.*TargetB> clazz\\)," - + " .*TargetB .*TargetFactories\\.createTargetB\\(@TargetType java.lang.Class<.*TargetB> clazz\\)," - + " .*TargetB .*TargetFactories\\.createTargetB\\(\\)."), - @Diagnostic(type = ErroneousIssue1242MapperMultipleSources.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = ".*TargetB does not have an accessible parameterless constructor\\.") + line = 21, + message = "Ambiguous factory methods found for creating TargetB: " + + "TargetB anotherTargetBCreator(SourceB source), " + + "TargetB TargetFactories.createTargetB(SourceB source, @TargetType Class clazz), " + + "TargetB TargetFactories.createTargetB(@TargetType Class clazz), " + + "TargetB TargetFactories.createTargetB(). " + + "See https://mapstruct.org/faq/#ambiguous for more info.") }) public void ambiguousMethodErrorForTwoFactoryMethodsWithSourceParam() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceA.java index 874732508a..5afee73549 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceA.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceA.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceB.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceB.java index caf301c803..53a16640db 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceB.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/SourceB.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetA.java index a100c51a70..1b861c8029 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetA.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetA.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetB.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetB.java index f6b690073b..6a28adc828 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetB.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetB.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; @@ -22,6 +9,7 @@ * @author Andreas Gudian */ class TargetB { + protected String value; private final String passedViaConstructor; TargetB(String passedViaConstructor) { @@ -31,4 +19,12 @@ class TargetB { String getPassedViaConstructor() { return passedViaConstructor; } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetFactories.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetFactories.java index b4476bcd2d..bdec6b5ed8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetFactories.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1242/TargetFactories.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1242; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/Issue1244Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/Issue1244Test.java index 42b8076f17..231ff67334 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/Issue1244Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/Issue1244Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1244; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; import static org.assertj.core.api.Assertions.assertThat; @@ -31,11 +16,10 @@ * @author Filip Hrisafov */ @IssueKey("1244") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses( SizeMapper.class ) public class Issue1244Test { - @Test + @ProcessorTest public void properlyCreatesMapperWithSizeAsParameterName() { SizeMapper.SizeHolder sizeHolder = new SizeMapper.SizeHolder(); sizeHolder.setSize( "size" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/SizeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/SizeMapper.java index 8de1c6874c..0e647360e7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/SizeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1244/SizeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1244; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoIn.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoIn.java index 5012d60b85..69a19454e0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoIn.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoIn.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoOut.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoOut.java index 1a5cefc57f..667a5e02ad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoOut.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/DtoOut.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalData.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalData.java index aafdc6838d..2c9684584f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalData.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalData.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalDto.java index 6e3ec8a5af..a69385dd6f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/InternalDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Mapper.java index ba3086631c..5e216a334f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Test.java index beaef236cf..1dd12d6e23 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/Issue1247Test.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; import java.util.Arrays; import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -33,7 +18,6 @@ * @author Filip Hrisafov */ @IssueKey("1247") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Issue1247Mapper.class, DtoIn.class, @@ -46,7 +30,7 @@ }) public class Issue1247Test { - @Test + @ProcessorTest public void shouldCorrectlyUseMappings() { DtoIn in = new DtoIn( "data", "data2" ); @@ -61,7 +45,7 @@ public void shouldCorrectlyUseMappings() { assertThat( out.getInternal().getInternalData().getList() ).containsExactly( "first", "second" ); } - @Test + @ProcessorTest public void shouldCorrectlyUseMappingsWithConstantsExpressionsAndDefaults() { DtoIn in = new DtoIn( "data", "data2" ); @@ -81,7 +65,7 @@ public void shouldCorrectlyUseMappingsWithConstantsExpressionsAndDefaults() { assertThat( out.getInternal().getInternalData().getDefaultValue() ).isEqualTo( "data2" ); } - @Test + @ProcessorTest public void shouldCorrectlyUseMappingsWithConstantsExpressionsAndUseDefault() { DtoIn in = new DtoIn( "data", null ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherDtoOut.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherDtoOut.java index 36439f0ceb..80660b0bf1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherDtoOut.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherDtoOut.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalData.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalData.java index f06bacde4f..3773029266 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalData.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalData.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalDto.java index 91fe5d7eaf..25411c207c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1247/OtherInternalDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1247; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java index 0b9c107ca8..edb36b1d38 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/AbstractA.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1255; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java index 924e8533bc..9d27fdf681 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/Issue1255Test.java @@ -1,36 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1255; -import static org.assertj.core.api.Assertions.assertThat; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * * @author Sjaak Derksen */ @IssueKey("1255") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ AbstractA.class, SomeA.class, @@ -39,8 +24,8 @@ SomeMapperConfig.class}) public class Issue1255Test { - @Test - public void shouldMapSomeBToSomeAWithoutField1() throws Exception { + @ProcessorTest + public void shouldMapSomeBToSomeAWithoutField1() { SomeB someB = new SomeB(); someB.setField1( "value1" ); someB.setField2( "value2" ); @@ -53,8 +38,8 @@ public void shouldMapSomeBToSomeAWithoutField1() throws Exception { assertThat( someA.getField2() ).isEqualTo( someB.getField2() ); } - @Test - public void shouldMapSomeAToSomeB() throws Exception { + @ProcessorTest + public void shouldMapSomeAToSomeB() { SomeA someA = new SomeA(); someA.setField1( "value1" ); someA.setField2( "value2" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java index a9e030f7dc..cea619e6fd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeA.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1255; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java index 1820b96764..9f6019fdee 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeB.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1255; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java index 0fb3137c05..b1350d991c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1255; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java index dfe711f50e..145de5b95c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1255/SomeMapperConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1255; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/Issue1269Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/Issue1269Test.java index 9329eddabb..668b9e5110 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/Issue1269Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/Issue1269Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269; import java.util.Arrays; import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._1269.dto.VehicleDto; import org.mapstruct.ap.test.bugs._1269.dto.VehicleImageDto; import org.mapstruct.ap.test.bugs._1269.dto.VehicleInfoDto; @@ -31,8 +16,8 @@ import org.mapstruct.ap.test.bugs._1269.model.VehicleImage; import org.mapstruct.ap.test.bugs._1269.model.VehicleTypeInfo; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -40,7 +25,6 @@ * @author Filip Hrisafov */ @IssueKey( "1269" ) -@RunWith( AnnotationProcessorTestRunner.class ) @WithClasses( { VehicleDto.class, VehicleImageDto.class, @@ -52,7 +36,7 @@ } ) public class Issue1269Test { - @Test + @ProcessorTest public void shouldMapNestedPropertiesCorrectly() { VehicleTypeInfo sourceTypeInfo = new VehicleTypeInfo( "Opel", "Corsa", 3 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleDto.java index 046972b5f3..bc6842cfef 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleImageDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleImageDto.java index 50de755f7b..3e0b0b8414 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleImageDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleImageDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleInfoDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleInfoDto.java index 55f6ef7ddc..48255fcb25 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleInfoDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/dto/VehicleInfoDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/mapper/VehicleMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/mapper/VehicleMapper.java index 9db3fdfb0a..eba04c130b 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/mapper/VehicleMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/mapper/VehicleMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/Vehicle.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/Vehicle.java index ba19f8d16c..9b02435a16 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/Vehicle.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/Vehicle.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.model; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleImage.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleImage.java index f9ff4fed44..19ac16c8ad 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleImage.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleImage.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.model; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleTypeInfo.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleTypeInfo.java index dc803dc520..7310e63c3d 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleTypeInfo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1269/model/VehicleTypeInfo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1269.model; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Dto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Dto.java index b38fcaec61..9c912c2210 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Dto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Dto.java @@ -1,29 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1273; -import java.util.ArrayList; import java.util.List; public class Dto { - List longs = new ArrayList(); + List longs; public List getLongs() { return longs; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Entity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Entity.java index f93a3578f2..fa1c1d47f5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Entity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Entity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1273; @@ -23,7 +10,7 @@ public class Entity { - List longs = new ArrayList(); + List longs = new ArrayList<>(); public List getLongs() { return longs; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnDefault.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnDefault.java index 38e2a1f5ac..0b31e1d734 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnDefault.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnDefault.java @@ -1,29 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1273; +import java.util.ArrayList; + import org.mapstruct.Mapper; -import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ObjectFactory; -@Mapper( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT ) +@Mapper public interface EntityMapperReturnDefault { Dto asTarget(Entity entity); + @ObjectFactory + default Dto createDto() { + Dto result = new Dto(); + result.setLongs( new ArrayList<>( ) ); + return result; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnNull.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnNull.java index bd9c284b22..331de18d13 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnNull.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/EntityMapperReturnNull.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1273; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Issue1273Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Issue1273Test.java index f50e9c2c9c..9874b33436 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Issue1273Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1273/Issue1273Test.java @@ -1,38 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1273; -import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + @IssueKey( "1273" ) -@RunWith( AnnotationProcessorTestRunner.class ) @WithClasses( { EntityMapperReturnDefault.class, EntityMapperReturnNull.class, Dto.class, Entity.class } ) public class Issue1273Test { - @Test + @ProcessorTest public void shouldCorrectlyMapCollectionWithNullValueMappingStrategyReturnDefault() { EntityMapperReturnDefault entityMapper = Mappers.getMapper( EntityMapperReturnDefault.class ); @@ -42,7 +26,7 @@ public void shouldCorrectlyMapCollectionWithNullValueMappingStrategyReturnDefaul assertThat( dto.getLongs() ).isNotNull(); } - @Test + @ProcessorTest public void shouldCorrectlyMapCollectionWithNullValueMappingStrategyReturnNull() { EntityMapperReturnNull entityMapper = Mappers.getMapper( EntityMapperReturnNull.class ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousInverseTargetHasNoSuitableConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousInverseTargetHasNoSuitableConstructorMapper.java index db16b4c166..fd109d0dc6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousInverseTargetHasNoSuitableConstructorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousInverseTargetHasNoSuitableConstructorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1283; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousTargetHasNoSuitableConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousTargetHasNoSuitableConstructorMapper.java index fac5677d87..259285993c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousTargetHasNoSuitableConstructorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/ErroneousTargetHasNoSuitableConstructorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1283; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Issue1283Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Issue1283Test.java index 951976d53f..1879c9398b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Issue1283Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Issue1283Test.java @@ -1,67 +1,51 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1283; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov */ @IssueKey("1283") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Source.class, Target.class }) public class Issue1283Test { - @Test + @ProcessorTest @WithClasses(ErroneousInverseTargetHasNoSuitableConstructorMapper.class) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousInverseTargetHasNoSuitableConstructorMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35L, - messageRegExp = ".*\\._1283\\.Source does not have an accessible parameterless constructor" + line = 22L, + message = "Source does not have an accessible constructor." ) } ) public void inheritInverseConfigurationReturnTypeHasNoSuitableConstructor() { } - @Test + @ProcessorTest @WithClasses(ErroneousTargetHasNoSuitableConstructorMapper.class) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousTargetHasNoSuitableConstructorMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 31L, - messageRegExp = ".*\\._1283\\.Source does not have an accessible parameterless constructor" + line = 18L, + message = "Source does not have an accessible constructor." ) } ) diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Source.java index a55fa332c0..227296ad25 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1283; @@ -25,7 +12,7 @@ public class Source { private String source; - public Source(String source) { + private Source(String source) { this.source = source; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Target.java index 2285de7015..02a26968f8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1283/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1283; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Mapper.java index f7e09e6d00..b20ef4a72d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1320; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Test.java index 563ffbfd2f..b84fe2d8e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Issue1320Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1320; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -30,14 +15,13 @@ * @author Filip Hrisafov */ @IssueKey("1320") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Issue1320Mapper.class, Target.class }) public class Issue1320Test { - @Test + @ProcessorTest public void shouldCreateDeepNestedConstantsCorrectly() { Target target = Issue1320Mapper.INSTANCE.map( 10 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Target.java index b848d25f38..3fb27141eb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1320/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1320; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Mapper.java index b4b6b7022f..faff474e00 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1338; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Test.java index 08a4b3ccd8..924f5e8c86 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Issue1338Test.java @@ -1,38 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1338; import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.atIndex; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1338") @WithClasses({ Issue1338Mapper.class, @@ -41,15 +24,14 @@ }) public class Issue1338Test { - @Test + @ProcessorTest public void shouldCorrectlyUseAdder() { Source source = new Source(); source.setProperties( Arrays.asList( "first", "second" ) ); Target target = Issue1338Mapper.INSTANCE.map( source ); - assertThat( target ) - .extracting( "properties" ) - .contains( Arrays.asList( "first", "second" ), atIndex( 0 ) ); + assertThat( target.getProperties() ) + .containsExactly( "first", "second" ); Source mapped = Issue1338Mapper.INSTANCE.map( target ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Source.java index 1700fd62d0..f5157b9690 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1338; @@ -30,7 +17,7 @@ public class Source { public void addProperty(String property) { if ( properties == null ) { - properties = new ArrayList(); + properties = new ArrayList<>(); } properties.add( property ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Target.java index 0ee75087f0..a06a52c16a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1338/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1338; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Callback.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Callback.java index 5724322c01..f7f42079be 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Callback.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Callback.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1339; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Mapper.java index d11d41f4b9..d3463e712b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1339; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Test.java index 63dcc1f100..fa1caff745 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1339/Issue1339Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1339; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -33,11 +18,10 @@ Issue1339Mapper.class, Callback.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1339") public class Issue1339Test { - @Test + @ProcessorTest public void shouldCompile() { Issue1339Mapper.Source source = new Issue1339Mapper.Source(); source.field = "test"; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Mapper.java index 72cd7b2997..2b511956f2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1340; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Test.java index b303beb4d9..3135dfff67 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1340/Issue1340Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1340; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -31,10 +16,9 @@ Issue1340Mapper.class }) @IssueKey("1340") -@RunWith(AnnotationProcessorTestRunner.class) public class Issue1340Test { - @Test + @ProcessorTest public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Mapper.java index 5b8733b951..b2d89c96e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1345; @@ -40,8 +27,17 @@ public interface Issue1345Mapper { class A { + private String value; private String readOnlyProperty; + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + public String getReadOnlyProperty() { return readOnlyProperty; } @@ -49,8 +45,17 @@ public String getReadOnlyProperty() { class B { + private String value; private String property; + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + public String getProperty() { return property; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Test.java index 0397fdc89d..7be9b0edc1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1345/Issue1345Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1345; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Sjaak Derksen @@ -31,10 +16,9 @@ Issue1345Mapper.class }) @IssueKey("1345") -@RunWith(AnnotationProcessorTestRunner.class) public class Issue1345Test { - @Test + @ProcessorTest public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Mapper.java index f94551460d..e22bd946a1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1353; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Test.java index ad074548ee..4398d6ebcd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Issue1353Test.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1353; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -33,7 +18,6 @@ * @author Jeffrey Smyth */ @IssueKey ("1353") -@RunWith (AnnotationProcessorTestRunner.class) @WithClasses ({ Issue1353Mapper.class, Source.class, @@ -41,20 +25,20 @@ }) public class Issue1353Test { - @Test + @ProcessorTest @ExpectedCompilationOutcome ( value = CompilationResult.SUCCEEDED, diagnostics = { @Diagnostic (type = Issue1353Mapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 35, - messageRegExp = "The property named \" source.string1\" has whitespaces," + line = 22, + message = "The property named \" source.string1\" has whitespaces," + " using trimmed property \"source.string1\" instead." ), @Diagnostic (type = Issue1353Mapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 35, - messageRegExp = "The property named \"string2 \" has whitespaces," + line = 22, + message = "The property named \"string2 \" has whitespaces," + " using trimmed property \"string2\" instead." ) } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Source.java index d216236bf2..1a6c62db39 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1353; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Target.java index 3197f092d7..15ece1eb3f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1353/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1353; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Mapper.java index a0270788d6..6b4e1257b0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1359; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Test.java index 9e4d8276a9..a412cd19f6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Issue1359Test.java @@ -1,34 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1359; import java.util.HashSet; import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.atIndex; +import static org.assertj.core.api.InstanceOfAssertFactories.ITERABLE; /** * @author Filip Hrisafov @@ -38,22 +23,21 @@ Source.class, Target.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) @IssueKey( "1359" ) public class Issue1359Test { - @Test + @ProcessorTest public void shouldCompile() { Target target = new Target(); - assertThat( target ).extracting( "properties" ).contains( null, atIndex( 0 ) ); + assertThat( target ).extracting( "properties" ).isNull(); - Set properties = new HashSet(); + Set properties = new HashSet<>(); properties.add( "first" ); Source source = new Source( properties ); Issue1359Mapper.INSTANCE.map( target, source ); - assertThat( target ).extracting( "properties" ).contains( properties, atIndex( 0 ) ); + assertThat( target ).extracting( "properties", ITERABLE ).containsExactly( "first" ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Source.java index 7b4bb0d2d0..7646bad7c6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1359; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Target.java index 196118eb59..9aa853ffff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1359/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1359; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Mapper.java index 3890db403d..5fb62711db 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Test.java index 85e70dd0dc..9dcb9655f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Issue1375Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1375; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -34,11 +19,10 @@ Source.class, Issue1375Mapper.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) @IssueKey( "1375" ) public class Issue1375Test { - @Test + @ProcessorTest public void shouldGenerateCorrectMapperWhenIntermediaryReadAccessorIsMissing() { Target target = Issue1375Mapper.INSTANCE.map( new Source( "test value" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Source.java index 4d6b7bfa07..55b7de30eb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Target.java index 3cb4996cdf..a7c160aaa5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1375/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Issue1395Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Issue1395Mapper.java deleted file mode 100644 index 96ba139cb8..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Issue1395Mapper.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._1395; - -import org.mapstruct.InjectionStrategy; -import org.mapstruct.Mapper; - -/** - * @author Filip Hrisafov - */ -@Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR, componentModel = "spring", uses = NotUsedService.class) -public interface Issue1395Mapper { - - Target map(Source source); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Issue1395Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Issue1395Test.java deleted file mode 100644 index b1333a4a09..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Issue1395Test.java +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._1395; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mapstruct.ap.testutil.IssueKey; -import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; - -/** - * @author Filip Hrisafov - */ -@WithClasses( { - Issue1395Mapper.class, - NotUsedService.class, - Source.class, - Target.class -} ) -@RunWith( AnnotationProcessorTestRunner.class ) -@IssueKey( "1395" ) -public class Issue1395Test { - - @Test - public void shouldGenerateValidCode() { - - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/NotUsedService.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/NotUsedService.java deleted file mode 100644 index 95f39909c2..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/NotUsedService.java +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._1395; - -/** - * @author Filip Hrisafov - */ -public interface NotUsedService { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Source.java deleted file mode 100644 index f79943b2ef..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Source.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._1395; - -/** - * @author Filip Hrisafov - */ -public class Source { - - private String value; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Target.java deleted file mode 100644 index 1eb6c41522..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/Target.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._1395; - -/** - * @author Filip Hrisafov - */ -public class Target { - - private String value; - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Issue1395Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Issue1395Mapper.java new file mode 100644 index 0000000000..4e48020c8d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Issue1395Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1395.spring; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; + +/** + * @author Filip Hrisafov + */ +@Mapper(injectionStrategy = InjectionStrategy.CONSTRUCTOR, componentModel = MappingConstants.ComponentModel.SPRING, + uses = NotUsedService.class) +public interface Issue1395Mapper { + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Issue1395Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Issue1395Test.java new file mode 100644 index 0000000000..3417fbd707 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Issue1395Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1395.spring; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; + +/** + * @author Filip Hrisafov + */ +@WithClasses( { + Issue1395Mapper.class, + NotUsedService.class, + Source.class, + Target.class +} ) +@WithSpring +@IssueKey( "1395" ) +public class Issue1395Test { + + @ProcessorTest + public void shouldGenerateValidCode() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/NotUsedService.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/NotUsedService.java new file mode 100644 index 0000000000..ba47cf179f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/NotUsedService.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1395.spring; + +/** + * @author Filip Hrisafov + */ +public interface NotUsedService { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Source.java new file mode 100644 index 0000000000..8f2a52d462 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1395.spring; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Target.java new file mode 100644 index 0000000000..1ba393dbe0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1395/spring/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1395.spring; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Mapper.java index f61f8c4a7c..2e500aa285 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1425; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Test.java index 15ee02797d..a71c33c396 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Issue1425Test.java @@ -1,29 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1425; import org.joda.time.LocalDate; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJoda; import static org.assertj.core.api.Assertions.assertThat; @@ -35,11 +21,11 @@ Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1425") +@WithJoda public class Issue1425Test { - @Test + @ProcessorTest public void shouldTestMappingLocalDates() { Source source = new Source(); source.setValue( LocalDate.parse( "2018-04-18" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Source.java index 2c97acc5fa..1a739197d8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1425; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Target.java index da1d0394ae..57d96dad49 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1425/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1425; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Config.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Config.java new file mode 100644 index 0000000000..b76e6538f2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Config.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1435; + +import java.util.Objects; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingInheritanceStrategy; + +@MapperConfig(mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG, imports = Objects.class) +public interface Config { + @Mapping(expression = "java( Objects.equals( source.getName(), \"Rainbow Dash\" ) )", target = "rainbowDash") + OutObject map(InObject source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/InObject.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/InObject.java new file mode 100644 index 0000000000..27b6fa2742 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/InObject.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1435; + +public class InObject { + + private final String name; + + public InObject(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Issue1435Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Issue1435Mapper.java new file mode 100644 index 0000000000..c98eba2ed2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Issue1435Mapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1435; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper(config = Config.class) +public interface Issue1435Mapper { + + Issue1435Mapper INSTANCE = Mappers.getMapper( Issue1435Mapper.class ); + + OutObject map(InObject source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Issue1435Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Issue1435Test.java new file mode 100644 index 0000000000..2fa173cac1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/Issue1435Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1435; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1435") +@WithClasses({ + Config.class, + Issue1435Mapper.class, + InObject.class, + OutObject.class, +}) +public class Issue1435Test { + @ProcessorTest + public void mustNotSetListToNull() { + InObject source = new InObject( "Rainbow Dash" ); + + OutObject result = Issue1435Mapper.INSTANCE.map( source ); + + assertThat( result.isRainbowDash() ).isTrue(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/OutObject.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/OutObject.java new file mode 100644 index 0000000000..b3a16f2250 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1435/OutObject.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1435; + +public class OutObject { + + private boolean isRainbowDash; + + public boolean isRainbowDash() { + return isRainbowDash; + } + + public void setRainbowDash(boolean rainbowDash) { + isRainbowDash = rainbowDash; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Auction.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Auction.java index 60f32b6500..11f44281d5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Auction.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Auction.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1453; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/AuctionDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/AuctionDto.java index c3a68bba09..5b8fd42a25 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/AuctionDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/AuctionDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1453; @@ -37,7 +24,7 @@ List takePayments() { } public void setPayments(List payments) { - this.payments = payments == null ? null : new ArrayList( payments ); + this.payments = payments == null ? null : new ArrayList<>( payments ); } List takeOtherPayments() { @@ -53,7 +40,7 @@ public void setOtherPayments(List otherPayments) { } public void setMapPayments(Map mapPayments) { - this.mapPayments = mapPayments == null ? null : new HashMap( mapPayments ); + this.mapPayments = mapPayments == null ? null : new HashMap<>( mapPayments ); } public Map getMapSuperPayments() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Mapper.java index fa3e0b4c54..d6ba8b9917 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1453; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Test.java index 47ece0437f..d112df0355 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Issue1453Test.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1453; import java.util.Arrays; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; @@ -34,7 +19,6 @@ * @author Filip Hrisafov */ @IssueKey("1453") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Auction.class, AuctionDto.class, @@ -44,10 +28,10 @@ }) public class Issue1453Test { - @Rule - public GeneratedSource source = new GeneratedSource().addComparisonToFixtureFor( Issue1453Mapper.class ); + @RegisterExtension + final GeneratedSource source = new GeneratedSource().addComparisonToFixtureFor( Issue1453Mapper.class ); - @Test + @ProcessorTest public void shouldGenerateCorrectCode() { AuctionDto target = Issue1453Mapper.INSTANCE.map( new Auction( diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Payment.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Payment.java index e3ec1a7f03..f03461e10f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Payment.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/Payment.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1453; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/PaymentDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/PaymentDto.java index 0763b24416..68963c7353 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/PaymentDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1453/PaymentDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1453; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/BookMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/BookMapper.java new file mode 100644 index 0000000000..bbef1fe3a8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/BookMapper.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public abstract class BookMapper { + + public static final BookMapper INSTANCE = Mappers.getMapper( BookMapper.class ); + + public abstract TargetBook mapBook(SourceBook sourceBook, String authorFirstName, String authorLastName); + + @AfterMapping + protected void fillAuthor(@MappingTarget TargetBook targetBook, String authorFirstName, String authorLastName) { + targetBook.setAuthorFirstName( authorFirstName ); + targetBook.setAuthorLastName( authorLastName ); + } + + @AfterMapping + protected void withoutAuthorNames(@MappingTarget TargetBook targetBook) { + targetBook.setAfterMappingWithoutAuthorName( true ); + } + + @AfterMapping + protected void withOnlyFirstName(@MappingTarget TargetBook targetBook, String authorFirstName) { + targetBook.setAfterMappingWithOnlyFirstName( authorFirstName ); + } + + @AfterMapping + protected void withOnlyLastName(@MappingTarget TargetBook targetBook, String authorLastName) { + targetBook.setAfterMappingWithOnlyLastName( authorLastName ); + } + + @AfterMapping + protected void withDifferentVariableName(@MappingTarget TargetBook targetBook, String author) { + targetBook.setAfterMappingWithDifferentVariableName( true ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/DifferentOrderingBookMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/DifferentOrderingBookMapper.java new file mode 100644 index 0000000000..c2ac556bab --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/DifferentOrderingBookMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public abstract class DifferentOrderingBookMapper { + + public static final DifferentOrderingBookMapper INSTANCE = Mappers.getMapper( DifferentOrderingBookMapper.class ); + + public abstract TargetBook mapBook(SourceBook sourceBook, String authorFirstName, String authorLastName); + + @AfterMapping + protected void fillAuthor(String authorLastName, String authorFirstName, @MappingTarget TargetBook targetBook) { + targetBook.setAuthorLastName( authorLastName ); + targetBook.setAuthorFirstName( authorFirstName ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/ErroneousBookMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/ErroneousBookMapper.java new file mode 100644 index 0000000000..a7314bbbad --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/ErroneousBookMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public abstract class ErroneousBookMapper { + + public static final ErroneousBookMapper INSTANCE = Mappers.getMapper( ErroneousBookMapper.class ); + + public abstract TargetBook mapBook(SourceBook sourceBook, String authorFirstName, String authorLastName); + + @AfterMapping + protected void fillAuthor(@MappingTarget TargetBook targetBook, String authorFirstN, String authorLastN) { + targetBook.setAuthorFirstName( authorFirstN ); + targetBook.setAuthorLastName( authorLastN ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/Issue1457Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/Issue1457Test.java new file mode 100644 index 0000000000..de1160771a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/Issue1457Test.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +import org.junit.jupiter.api.BeforeEach; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + SourceBook.class, + TargetBook.class +}) +@IssueKey("1457") +public class Issue1457Test { + + private SourceBook sourceBook; + private String authorFirstName; + private String authorLastName; + + @BeforeEach + public void setup() { + sourceBook = new SourceBook(); + sourceBook.setIsbn( "3453146972" ); + sourceBook.setTitle( "Per Anhalter durch die Galaxis" ); + + authorFirstName = "Douglas"; + authorLastName = "Adams"; + } + + @ProcessorTest + @WithClasses({ + BookMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = @Diagnostic( + message = + "Lifecycle method has multiple matching parameters (e. g. same type), in this case please ensure to " + + "name the parameters in the lifecycle and mapping method identical. This lifecycle method will " + + "not be used for the mapping method 'org.mapstruct.ap.test.bugs._1457.TargetBook mapBook(org" + + ".mapstruct.ap.test.bugs._1457.SourceBook sourceBook, java.lang.String authorFirstName, java.lang" + + ".String authorLastName)'.", + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 43 + ) + ) + public void testMapperWithMatchingParameterNames() { + TargetBook targetBook = BookMapper.INSTANCE.mapBook( sourceBook, authorFirstName, authorLastName ); + + assertTargetBookMatchesSourceBook( targetBook ); + + assertThat( targetBook.isAfterMappingWithoutAuthorName() ).isTrue(); + assertThat( targetBook.getAfterMappingWithOnlyFirstName() ).isEqualTo( authorFirstName ); + assertThat( targetBook.getAfterMappingWithOnlyLastName() ).isEqualTo( authorLastName ); + assertThat( targetBook.isAfterMappingWithDifferentVariableName() ).isFalse(); + } + + @ProcessorTest + @WithClasses({ + DifferentOrderingBookMapper.class + }) + public void testMapperWithMatchingParameterNamesAndDifferentOrdering() { + TargetBook targetBook = DifferentOrderingBookMapper.INSTANCE.mapBook( + sourceBook, + authorFirstName, + authorLastName + ); + + assertTargetBookMatchesSourceBook( targetBook ); + } + + @ProcessorTest + @WithClasses({ + ObjectFactoryBookMapper.class + }) + public void testMapperWithObjectFactory() { + TargetBook targetBook = ObjectFactoryBookMapper.INSTANCE.mapBook( + sourceBook, + authorFirstName, + authorLastName + ); + + assertTargetBookMatchesSourceBook( targetBook ); + } + + private void assertTargetBookMatchesSourceBook(TargetBook targetBook) { + assertThat( sourceBook.getIsbn() ).isEqualTo( targetBook.getIsbn() ); + assertThat( sourceBook.getTitle() ).isEqualTo( targetBook.getTitle() ); + assertThat( authorFirstName ).isEqualTo( targetBook.getAuthorFirstName() ); + assertThat( authorLastName ).isEqualTo( targetBook.getAuthorLastName() ); + } + + @ProcessorTest + @WithClasses({ + ErroneousBookMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = @Diagnostic( + message = + "Lifecycle method has multiple matching parameters (e. g. same type), in this case please ensure to " + + "name the parameters in the lifecycle and mapping method identical. This lifecycle method will " + + "not be used for the mapping method 'org.mapstruct.ap.test.bugs._1457.TargetBook mapBook(org" + + ".mapstruct.ap.test.bugs._1457.SourceBook sourceBook, java.lang.String authorFirstName, java.lang" + + ".String authorLastName)'.", + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 22 + ) + ) + public void testMapperWithoutMatchingParameterNames() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/ObjectFactoryBookMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/ObjectFactoryBookMapper.java new file mode 100644 index 0000000000..038b44653c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/ObjectFactoryBookMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +import org.mapstruct.Mapper; +import org.mapstruct.ObjectFactory; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public abstract class ObjectFactoryBookMapper { + + public static final ObjectFactoryBookMapper INSTANCE = Mappers.getMapper( ObjectFactoryBookMapper.class ); + + public abstract TargetBook mapBook(SourceBook sourceBook, String authorFirstName, String authorLastName); + + @ObjectFactory + protected TargetBook createTargetBook(String authorFirstName, String authorLastName) { + TargetBook targetBook = new TargetBook(); + targetBook.setAuthorFirstName( authorFirstName ); + targetBook.setAuthorLastName( authorLastName ); + + return targetBook; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/SourceBook.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/SourceBook.java new file mode 100644 index 0000000000..650e51fe4c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/SourceBook.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +public class SourceBook { + private String isbn; + private String title; + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/TargetBook.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/TargetBook.java new file mode 100644 index 0000000000..1698c537f7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1457/TargetBook.java @@ -0,0 +1,83 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1457; + +public class TargetBook { + + private String isbn; + private String title; + private String authorFirstName; + private String authorLastName; + + private boolean afterMappingWithoutAuthorName; + private String afterMappingWithOnlyFirstName; + private String afterMappingWithOnlyLastName; + private boolean afterMappingWithDifferentVariableName; + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthorFirstName() { + return authorFirstName; + } + + public void setAuthorFirstName(String authorFirstName) { + this.authorFirstName = authorFirstName; + } + + public String getAuthorLastName() { + return authorLastName; + } + + public void setAuthorLastName(String authorLastName) { + this.authorLastName = authorLastName; + } + + public boolean isAfterMappingWithoutAuthorName() { + return afterMappingWithoutAuthorName; + } + + public void setAfterMappingWithoutAuthorName(boolean afterMappingWithoutAuthorName) { + this.afterMappingWithoutAuthorName = afterMappingWithoutAuthorName; + } + + public String getAfterMappingWithOnlyFirstName() { + return afterMappingWithOnlyFirstName; + } + + public void setAfterMappingWithOnlyFirstName(String afterMappingWithOnlyFirstName) { + this.afterMappingWithOnlyFirstName = afterMappingWithOnlyFirstName; + } + + public String getAfterMappingWithOnlyLastName() { + return afterMappingWithOnlyLastName; + } + + public void setAfterMappingWithOnlyLastName(String afterMappingWithOnlyLastName) { + this.afterMappingWithOnlyLastName = afterMappingWithOnlyLastName; + } + + public boolean isAfterMappingWithDifferentVariableName() { + return afterMappingWithDifferentVariableName; + } + + public void setAfterMappingWithDifferentVariableName(boolean afterMappingWithDifferentVariableName) { + this.afterMappingWithDifferentVariableName = afterMappingWithDifferentVariableName; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Mapper.java index 7f099a499f..1d0d4fccbb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460; @@ -31,13 +18,13 @@ public abstract class Issue1460Mapper { public abstract Target map(Source source); - public abstract String forceUsageOfIssue1460Enum(Issue1460Enum source); + public abstract Value forceUsageOfIssue1460Enum(Issue1460Enum source); - public abstract String forceUsageOfLocale(Locale source); + public abstract Value forceUsageOfLocale(Locale source); - public abstract String forceUsageOfLocalDate(LocalDate source); + public abstract Value forceUsageOfLocalDate(LocalDate source); - public abstract String forceUsageOfDateTime(DateTime source); + public abstract Value forceUsageOfDateTime(DateTime source); public static class Issue1460Enum { } @@ -50,4 +37,17 @@ public static class LocalDate { public static class DateTime { } + + public static class Value { + + private final T source; + + public Value(T source) { + this.source = source; + } + + public T getSource() { + return source; + } + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Test.java index 18ff7c5340..e9c97f39bc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Issue1460Test.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460; @@ -22,11 +9,10 @@ import java.util.Locale; import org.joda.time.DateTime; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJoda; import static org.assertj.core.api.Assertions.assertThat; @@ -38,11 +24,11 @@ Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1460") +@WithJoda public class Issue1460Test { - @Test + @ProcessorTest public void shouldTestMappingLocalDates() { long dateInMs = 1524693600000L; String dateAsString = "2018-04-26"; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Source.java index 2ac3f93026..c97909aeec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Target.java index dcb20fa6be..e680f7d29c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeMapper.java index a1da8a805b..b9bedfe451 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460.java8; @@ -31,8 +18,17 @@ public abstract class Issue1460JavaTimeMapper { public abstract Target map(Source source); - public abstract String forceUsageOfLocalDate(LocalDate source); + public abstract LocalTarget forceUsageOfLocalDate(LocalDate source); public static class LocalDate { } + + public static class LocalTarget { + + private final LocalDate source; + + public LocalTarget(LocalDate source) { + this.source = source; + } + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeTest.java index f0ffd86768..829402efaa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Issue1460JavaTimeTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460.java8; import java.time.LocalDate; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -36,11 +21,10 @@ Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1460") public class Issue1460JavaTimeTest { - @Test + @ProcessorTest public void shouldTestMappingLocalDates() { String dateAsString = "2018-04-26"; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Source.java index 6515c6fa82..76b5124d2e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460.java8; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Target.java index f7cf79ebb6..1a7554b54f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1460/java8/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1460.java8; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/BigDecimalWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/BigDecimalWrapper.java new file mode 100644 index 0000000000..d62464c11a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/BigDecimalWrapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +import java.math.BigDecimal; + +public class BigDecimalWrapper implements ValueWrapper { + + private final BigDecimal value; + + public BigDecimalWrapper(BigDecimal value) { + this.value = value; + } + + @Override + public BigDecimal getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Issue1482Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Issue1482Test.java new file mode 100644 index 0000000000..d59b58dbda --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Issue1482Test.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +import java.math.BigDecimal; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + Source.class, + Source2.class, + Target.class, + SourceEnum.class, + BigDecimalWrapper.class, + ValueWrapper.class +}) +@IssueKey(value = "1482") +public class Issue1482Test { + + @ProcessorTest + @WithClasses( SourceTargetMapper.class ) + public void testForward() { + + Source source = new Source(); + source.setTest( SourceEnum.VAL1 ); + source.setWrapper( new BigDecimalWrapper( new BigDecimal( 5 ) ) ); + + Target target = SourceTargetMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getTest() ).isEqualTo( "value1" ); + assertThat( target.getBigDecimal() ).isEqualTo( new BigDecimal( 5 ) ); + + } + + @ProcessorTest + @WithClasses( TargetSourceMapper.class ) + public void testReverse() { + + Target target = new Target(); + target.setBigDecimal( new BigDecimal( 5 ) ); + target.setTest( "VAL1" ); + + Source2 source2 = TargetSourceMapper.INSTANCE.map( target ); + + assertThat( source2 ).isNotNull(); + assertThat( source2.getTest() ).isEqualTo( SourceEnum.VAL1 ); + assertThat( source2.getWrapper().getValue() ).isEqualTo( new BigDecimal( 5 ) ); + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Source.java new file mode 100644 index 0000000000..78c98c8af7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Source.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +public class Source { + + private SourceEnum test; + private BigDecimalWrapper wrapper; + + public SourceEnum getTest() { + return test; + } + + public void setTest(SourceEnum test) { + this.test = test; + } + + public BigDecimalWrapper getWrapper() { + return wrapper; + } + + public void setWrapper(BigDecimalWrapper wrapper) { + this.wrapper = wrapper; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Source2.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Source2.java new file mode 100644 index 0000000000..3ef01c76bb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Source2.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +import java.math.BigDecimal; + +public class Source2 { + + private Enum test; + private ValueWrapper wrapper; + + public Enum getTest() { + return test; + } + + public void setTest(Enum test) { + this.test = test; + } + + public ValueWrapper getWrapper() { + return wrapper; + } + + public void setWrapper(ValueWrapper wrapper) { + this.wrapper = wrapper; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/SourceEnum.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/SourceEnum.java new file mode 100644 index 0000000000..d421b17ef1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/SourceEnum.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +public enum SourceEnum { + + VAL1( "value1" ), + VAL2( "value2" ); + + private final String val; + + SourceEnum(String val) { + this.val = val; + } + + public String toString() { + return val; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/SourceTargetMapper.java new file mode 100644 index 0000000000..01a50311ae --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/SourceTargetMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public abstract class SourceTargetMapper { + + public static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping( target = "bigDecimal", source = "wrapper" ) + abstract Target map(Source source); + + protected String map(Enum e) { + return e.toString(); + } + + protected T map(ValueWrapper in) { + return in.getValue(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Target.java new file mode 100644 index 0000000000..3c3ede8016 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/Target.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +import java.math.BigDecimal; + +public class Target { + + private String test; + private BigDecimal bigDecimal; + + public String getTest() { + return test; + } + + public void setTest(String test) { + this.test = test; + } + + public BigDecimal getBigDecimal() { + return bigDecimal; + } + + public void setBigDecimal(BigDecimal bigDecimal) { + this.bigDecimal = bigDecimal; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/TargetSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/TargetSourceMapper.java new file mode 100644 index 0000000000..2ac081f611 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/TargetSourceMapper.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +import java.math.BigDecimal; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetType; +import org.mapstruct.factory.Mappers; + +@Mapper +public abstract class TargetSourceMapper { + + public static final TargetSourceMapper INSTANCE = Mappers.getMapper( TargetSourceMapper.class ); + + @Mapping(target = "wrapper", source = "bigDecimal") + abstract Source2 map(Target target); + + protected > T map(String in, @TargetType Classclz ) { + if ( clz.isAssignableFrom( SourceEnum.class ) ) { + return (T) SourceEnum.valueOf( in ); + } + return null; + } + + protected ValueWrapper map(T in) { + if ( in instanceof BigDecimal ) { + return (ValueWrapper) new BigDecimalWrapper( (BigDecimal) in ); + + } + return null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/ValueWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/ValueWrapper.java new file mode 100644 index 0000000000..09f331c5ef --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1482/ValueWrapper.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1482; + +public interface ValueWrapper { + T getValue(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Mapper.java index eb54dc6c0c..044e714e65 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1523.java8; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Test.java index 0ebde15c2a..825e318356 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Issue1523Test.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1523.java8; @@ -22,13 +9,10 @@ import java.util.Calendar; import java.util.TimeZone; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.DefaultTimeZone; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -45,33 +29,20 @@ Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1523") +// we want to test that the timezone will correctly be used in mapped XMLGregorianCalendar and not the +// default one, so we must ensure that we use a different timezone than the default one -> set the default +// one explicitly to UTC +@DefaultTimeZone("UTC") public class Issue1523Test { - private static final TimeZone DEFAULT_TIMEZONE = TimeZone.getDefault(); - - @BeforeClass - public static void before() { - // we want to test that the timezone will correctly be used in mapped XMLGregorianCalendar and not the - // default one, so we must ensure that we use a different timezone than the default one -> set the default - // one explicitly to UTC - TimeZone.setDefault( TimeZone.getTimeZone( "UTC" ) ); - } - - @AfterClass - public static void after() { - // revert the changed default TZ - TimeZone.setDefault( DEFAULT_TIMEZONE ); - } - - @Test + @ProcessorTest public void testThatCorrectTimeZoneWillBeUsedInTarget() { Source source = new Source(); // default one was explicitly set to UTC, thus +01:00 is a different one source.setValue( ZonedDateTime.parse( "2018-06-15T00:00:00+01:00" ) ); Calendar cal = Calendar.getInstance( TimeZone.getTimeZone( "GMT+01:00" ) ); - cal.set( 2018, 02, 15, 00, 00, 00 ); + cal.set( 2018, Calendar.MARCH, 15, 00, 00, 00 ); source.setValue2( cal ); Target target = Issue1523Mapper.INSTANCE.map( source ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Source.java index 5ccb45d9cd..1075599c54 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1523.java8; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Target.java index 009c4ca62f..7492d58b99 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1523/java8/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._1523.java8; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Issue1541Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Issue1541Mapper.java new file mode 100644 index 0000000000..caafee8d3f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Issue1541Mapper.java @@ -0,0 +1,85 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1541; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeanMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; +import org.mapstruct.Named; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Bandowski + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) // IGNORE to keep this test-mapper small and clean +public abstract class Issue1541Mapper { + + public static final Issue1541Mapper INSTANCE = Mappers.getMapper( Issue1541Mapper.class ); + + public abstract Target mapWithVarArgs(String code, String... parameters); + + public abstract Target mapWithArray(String code, String[] parameters); + + @Mapping(target = "parameters2", source = "parameters") + public abstract Target mapWithReassigningVarArgs(String code, String... parameters); + + public abstract Target mapWithArrayAndVarArgs(String code, String[] parameters, String... parameters2); + + @Mappings({ + @Mapping(target = "parameters", ignore = true) + }) + @BeanMapping(qualifiedByName = "afterMappingParametersAsArray") + public abstract Target mapParametersAsArrayInAfterMapping(String code, String... parameters); + + @AfterMapping + @Named( "afterMappingParametersAsArray" ) + protected void afterMappingParametersAsArray(@MappingTarget Target target, String[] parameters) { + target.setAfterMappingWithArrayCalled( true ); + target.setParameters( parameters ); + } + + @Mappings({ + @Mapping(target = "parameters", ignore = true) + }) + @BeanMapping(qualifiedByName = "afterMappingParametersAsVarArgs") + public abstract Target mapParametersAsVarArgsInAfterMapping(String code, String... parameters); + + @AfterMapping + @Named( "afterMappingParametersAsVarArgs" ) + protected void afterMappingParametersAsVarArgs(@MappingTarget Target target, String... parameters) { + target.setAfterMappingWithVarArgsCalled( true ); + target.setParameters( parameters ); + } + + @Mapping(target = "parameters2", ignore = true) + @BeanMapping(qualifiedByName = "afterMappingContextAsVarArgsUsingVarArgs") + public abstract Target mapContextWithVarArgsInAfterMappingWithVarArgs(String code, String[] parameters, + @Context String... context); + + @AfterMapping + @Named( "afterMappingContextAsVarArgsUsingVarArgs" ) + protected void afterMappingContextAsVarArgsUsingVarArgs(@MappingTarget Target target, @Context String... context) { + target.setAfterMappingContextWithVarArgsAsVarArgsCalled( true ); + target.setParameters2( context ); + } + + @Mapping(target = "parameters2", ignore = true) + @BeanMapping(qualifiedByName = "afterMappingContextAsVarArgsUsingArray") + public abstract Target mapContextWithVarArgsInAfterMappingWithArray(String code, String[] parameters, + @Context String... context); + + @AfterMapping + @Named( "afterMappingContextAsVarArgsUsingArray" ) + protected void afterMappingContextAsVarArgsUsingArray(@MappingTarget Target target, @Context String[] context) { + target.setAfterMappingContextWithVarArgsAsArrayCalled( true ); + target.setParameters2( context ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Issue1541Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Issue1541Test.java new file mode 100644 index 0000000000..01f7ed92a9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Issue1541Test.java @@ -0,0 +1,145 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1541; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * + * @author Christian Bandowski + */ +@WithClasses({ + Issue1541Mapper.class, + Target.class +}) +@IssueKey("1541") +public class Issue1541Test { + + @ProcessorTest + public void testMappingWithVarArgs() { + Target target = Issue1541Mapper.INSTANCE.mapWithVarArgs( "code", "1", "2" ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testMappingWithArray() { + Target target = Issue1541Mapper.INSTANCE.mapWithArray( "code", new String[] { "1", "2" } ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.getParameters2() ).isNull(); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testMappingWithVarArgsReassignment() { + Target target = Issue1541Mapper.INSTANCE.mapWithReassigningVarArgs( "code", "1", "2" ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).isNull(); + assertThat( target.getParameters2() ).contains( "1", "2" ); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testMappingWithArrayAndVarArgs() { + Target target = Issue1541Mapper.INSTANCE.mapWithArrayAndVarArgs( "code", new String[] { "1", "2" }, "3", "4" ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.getParameters2() ).contains( "3", "4" ); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testVarArgsInAfterMappingAsArray() { + Target target = Issue1541Mapper.INSTANCE.mapParametersAsArrayInAfterMapping( "code", "1", "2" ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.getParameters2() ).isNull(); + assertThat( target.isAfterMappingWithArrayCalled() ).isTrue(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testVarArgsInAfterMappingAsVarArgs() { + Target target = Issue1541Mapper.INSTANCE.mapParametersAsVarArgsInAfterMapping( "code", "1", "2" ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.getParameters2() ).isNull(); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isTrue(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testVarArgsInContextWithVarArgsAfterMapping() { + Target target = Issue1541Mapper.INSTANCE.mapContextWithVarArgsInAfterMappingWithVarArgs( + "code", + new String[] { "1", "2" }, + "3", + "4" + ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.getParameters2() ).contains( "3", "4" ); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isTrue(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isFalse(); + } + + @ProcessorTest + public void testVarArgsInContextWithArrayAfterMapping() { + Target target = Issue1541Mapper.INSTANCE.mapContextWithVarArgsInAfterMappingWithArray( + "code", + new String[] { "1", "2" }, + "3", + "4" + ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "code" ); + assertThat( target.getParameters() ).contains( "1", "2" ); + assertThat( target.getParameters2() ).contains( "3", "4" ); + assertThat( target.isAfterMappingWithArrayCalled() ).isFalse(); + assertThat( target.isAfterMappingWithVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsVarArgsCalled() ).isFalse(); + assertThat( target.isAfterMappingContextWithVarArgsAsArrayCalled() ).isTrue(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Target.java new file mode 100644 index 0000000000..b57c7a476f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1541/Target.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1541; + +public class Target { + private String code; + private String[] parameters; + private String[] parameters2; + + private boolean afterMappingWithVarArgsCalled = false; + private boolean afterMappingWithArrayCalled = false; + private boolean afterMappingContextWithVarArgsAsVarArgsCalled = false; + private boolean afterMappingContextWithVarArgsAsArrayCalled = false; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String[] getParameters() { + return parameters; + } + + public void setParameters(String[] parameters) { + this.parameters = parameters; + } + + public String[] getParameters2() { + return parameters2; + } + + public void setParameters2(String[] parameters2) { + this.parameters2 = parameters2; + } + + public boolean isAfterMappingWithVarArgsCalled() { + return afterMappingWithVarArgsCalled; + } + + public void setAfterMappingWithVarArgsCalled(boolean afterMappingWithVarArgsCalled) { + this.afterMappingWithVarArgsCalled = afterMappingWithVarArgsCalled; + } + + public boolean isAfterMappingWithArrayCalled() { + return afterMappingWithArrayCalled; + } + + public void setAfterMappingWithArrayCalled(boolean afterMappingWithArrayCalled) { + this.afterMappingWithArrayCalled = afterMappingWithArrayCalled; + } + + public boolean isAfterMappingContextWithVarArgsAsVarArgsCalled() { + return afterMappingContextWithVarArgsAsVarArgsCalled; + } + + public void setAfterMappingContextWithVarArgsAsVarArgsCalled( + boolean afterMappingContextWithVarArgsAsVarArgsCalled) { + this.afterMappingContextWithVarArgsAsVarArgsCalled = afterMappingContextWithVarArgsAsVarArgsCalled; + } + + public boolean isAfterMappingContextWithVarArgsAsArrayCalled() { + return afterMappingContextWithVarArgsAsArrayCalled; + } + + public void setAfterMappingContextWithVarArgsAsArrayCalled(boolean afterMappingContextWithVarArgsAsArrayCalled) { + this.afterMappingContextWithVarArgsAsArrayCalled = afterMappingContextWithVarArgsAsArrayCalled; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Issue1552Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Issue1552Mapper.java new file mode 100644 index 0000000000..ca97c0f0b4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Issue1552Mapper.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1552; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1552Mapper { + + Issue1552Mapper INSTANCE = Mappers.getMapper( Issue1552Mapper.class ); + + @Mappings({ + @Mapping(target = "first.value", constant = "constant"), + @Mapping(target = "second.value", source = "sourceTwo") + }) + Target twoArgsWithConstant(String sourceOne, String sourceTwo); + + @Mappings({ + @Mapping(target = "first.value", expression = "java(\"expression\")"), + @Mapping(target = "second.value", source = "sourceTwo") + }) + Target twoArgsWithExpression(String sourceOne, String sourceTwo); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Issue1552Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Issue1552Test.java new file mode 100644 index 0000000000..2dcaf182c6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Issue1552Test.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1552; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue1552Mapper.class, + Target.class +}) +@IssueKey("1552") +public class Issue1552Test { + + @ProcessorTest + public void shouldCompile() { + Target target = Issue1552Mapper.INSTANCE.twoArgsWithConstant( "first", "second" ); + + assertThat( target ).isNotNull(); + assertThat( target.getFirst() ).isNotNull(); + assertThat( target.getFirst().getValue() ).isEqualTo( "constant" ); + assertThat( target.getSecond() ).isNotNull(); + assertThat( target.getSecond().getValue() ).isEqualTo( "second" ); + + + target = Issue1552Mapper.INSTANCE.twoArgsWithExpression( "third", "fourth" ); + + assertThat( target ).isNotNull(); + assertThat( target.getFirst() ).isNotNull(); + assertThat( target.getFirst().getValue() ).isEqualTo( "expression" ); + assertThat( target.getSecond() ).isNotNull(); + assertThat( target.getSecond().getValue() ).isEqualTo( "fourth" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Target.java new file mode 100644 index 0000000000..93c80ebd1e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1552/Target.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1552; + +/** + * @author Filip Hrisafov + */ +public class Target { + private Inner first; + private Inner second; + + public Inner getFirst() { + return first; + } + + public void setFirst(Inner first) { + this.first = first; + } + + public Inner getSecond() { + return second; + } + + public void setSecond(Inner second) { + this.second = second; + } + + public static class Inner { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Car.java new file mode 100755 index 0000000000..d18c49246a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Car.java @@ -0,0 +1,81 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1558.java8; + +public class Car { + private boolean[] booleanData; + private byte[] data; + private short[] shortData; + private int[] intData; + private long[] longData; + private char[] charData; + private float[] floatData; + private double[] doubleData; + + public boolean[] getBooleanData() { + return booleanData; + } + + public void setBooleanData(boolean[] booleanData) { + this.booleanData = booleanData; + } + + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + public short[] getShortData() { + return shortData; + } + + public void setShortData(short[] shortData) { + this.shortData = shortData; + } + + public int[] getIntData() { + return intData; + } + + public void setIntData(int[] intData) { + this.intData = intData; + } + + public long[] getLongData() { + return longData; + } + + public void setLongData(long[] longData) { + this.longData = longData; + } + + public char[] getCharData() { + return charData; + } + + public void setCharData(char[] charData) { + this.charData = charData; + } + + public float[] getFloatData() { + return floatData; + } + + public void setFloatData(float[] floatData) { + this.floatData = floatData; + } + + public double[] getDoubleData() { + return doubleData; + } + + public void setDoubleData(double[] doubleData) { + this.doubleData = doubleData; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Car2.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Car2.java new file mode 100755 index 0000000000..337c5dd774 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Car2.java @@ -0,0 +1,89 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1558.java8; + +public class Car2 { + private boolean[] booleanData; + private byte[] data; + private short[] shortData; + private int[] intData; + private long[] longData; + private char[] charData; + private float[] floatData; + private double[] doubleData; + + @NotNull + public boolean[] getBooleanData() { + return booleanData; + } + + public void setBooleanData(boolean[] booleanData) { + this.booleanData = booleanData; + } + + @NotNull + public byte[] getData() { + return data; + } + + public void setData(byte[] data) { + this.data = data; + } + + @NotNull + public short[] getShortData() { + return shortData; + } + + public void setShortData(short[] shortData) { + this.shortData = shortData; + } + + @NotNull + public int[] getIntData() { + return intData; + } + + public void setIntData(int[] intData) { + this.intData = intData; + } + + @NotNull + public long[] getLongData() { + return longData; + } + + public void setLongData(long[] longData) { + this.longData = longData; + } + + @NotNull + public char[] getCharData() { + return charData; + } + + public void setCharData(char[] charData) { + this.charData = charData; + } + + @NotNull + public float[] getFloatData() { + return floatData; + } + + public void setFloatData(float[] floatData) { + this.floatData = floatData; + } + + @NotNull + public double[] getDoubleData() { + return doubleData; + } + + public void setDoubleData(double[] doubleData) { + this.doubleData = doubleData; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/CarMapper.java new file mode 100755 index 0000000000..2bd71d0c62 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/CarMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1558.java8; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + Car toCar(Car2 car2); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Issue1558Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Issue1558Test.java new file mode 100644 index 0000000000..38bafc1101 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/Issue1558Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1558.java8; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Sjaak Derksen + */ +@WithClasses({ + NotNull.class, + CarMapper.class, + Car.class, + Car2.class +}) +@IssueKey("1558") +public class Issue1558Test { + + @ProcessorTest + public void testShouldCompile() { + Car2 car = new Car2(); + Car target = CarMapper.INSTANCE.toCar( car ); + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/NotNull.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/NotNull.java new file mode 100644 index 0000000000..cf059a7c14 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1558/java8/NotNull.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1558.java8; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ + ElementType.METHOD, + ElementType.TYPE_USE +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface NotNull { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Issue1561Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Issue1561Mapper.java new file mode 100644 index 0000000000..95065f5dfb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Issue1561Mapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1561; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sebastian Haberey + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue1561Mapper { + + Issue1561Mapper + INSTANCE = Mappers.getMapper( Issue1561Mapper.class ); + + @Mapping( target = "nestedTarget.properties", source = "properties") + Target map(Source source); + + @InheritInverseConfiguration + Source map(Target target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Issue1561Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Issue1561Test.java new file mode 100644 index 0000000000..3e17e1c605 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Issue1561Test.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1561; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sebastian Haberey + */ +@IssueKey("1561") +@WithClasses({ + Issue1561Mapper.class, + Source.class, + Target.class, + NestedTarget.class +}) +public class Issue1561Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + Issue1561Mapper.class + ); + + @ProcessorTest + public void shouldCorrectlyUseAdder() { + + Source source = new Source(); + source.addProperty( "first" ); + source.addProperty( "second" ); + + Target target = Issue1561Mapper.INSTANCE.map( source ); + + assertThat( target.getNestedTarget().getProperties() ).containsExactly( "first", "second" ); + + Source mapped = Issue1561Mapper.INSTANCE.map( target ); + + assertThat( mapped.getProperties() ).containsExactly( "first", "second" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/NestedTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/NestedTarget.java new file mode 100644 index 0000000000..479d91f0e6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/NestedTarget.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1561; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +/** + * @author Sebastian Haberey + */ +public class NestedTarget { + + private List properties = new ArrayList<>(); + + public Stream getProperties() { + return properties.stream(); + } + + public void addProperty(String property) { + properties.add( property ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Source.java new file mode 100644 index 0000000000..5afe78f12c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Source.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1561; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Sebastian Haberey + */ +public class Source { + + private List properties = new ArrayList<>(); + + public List getProperties() { + return properties; + } + + public void addProperty(String property) { + properties.add( property ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Target.java new file mode 100644 index 0000000000..29c4f28b0c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1561/Target.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1561; + +public class Target { + + private NestedTarget nestedTarget; + + public NestedTarget getNestedTarget() { + return nestedTarget; + } + + public void setNestedTarget(NestedTarget nestedTarget) { + this.nestedTarget = nestedTarget; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/AbstractBuilder.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/AbstractBuilder.java new file mode 100644 index 0000000000..d97fccf9be --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/AbstractBuilder.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1566; + +/** + * @author Filip Hrisafov + */ +public abstract class AbstractBuilder> { + String id; + + @SuppressWarnings("unchecked") + public T id(final String id) { + this.id = id; + return (T) this; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Issue1566Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Issue1566Mapper.java new file mode 100644 index 0000000000..2ed6ed6d75 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Issue1566Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1566; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1566Mapper { + + Issue1566Mapper INSTANCE = Mappers.getMapper( Issue1566Mapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Issue1566Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Issue1566Test.java new file mode 100644 index 0000000000..5de2af6ab3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Issue1566Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1566; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + AbstractBuilder.class, + Issue1566Mapper.class, + Source.class, + Target.class +}) +@IssueKey("1566") +public class Issue1566Test { + + @ProcessorTest + public void genericMapperIsCorrectlyUsed() { + Source source = new Source(); + source.setId( "id-123" ); + source.setName( "Source" ); + + Target target = Issue1566Mapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( "id-123" ); + assertThat( target.getName() ).isEqualTo( "Source" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Source.java new file mode 100644 index 0000000000..73f3820d00 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Source.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1566; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Target.java new file mode 100644 index 0000000000..64a336af3c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1566/Target.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1566; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final String id; + private final String name; + + private Target(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends AbstractBuilder { + private String name; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Target build() { + return new Target( id, name ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Issue1569Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Issue1569Mapper.java new file mode 100644 index 0000000000..b97d0f75fb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Issue1569Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1569.java8; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1569Mapper { + + Issue1569Mapper INSTANCE = Mappers.getMapper( Issue1569Mapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Issue1569Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Issue1569Test.java new file mode 100644 index 0000000000..1bc7f4ca8d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Issue1569Test.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1569.java8; + +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneOffset; +import java.util.Date; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue1569Mapper.class, + Source.class, + Target.class +}) +@IssueKey("1569") +public class Issue1569Test { + + @ProcessorTest + public void shouldGenerateCorrectMapping() { + Source source = new Source(); + Date date = Date.from( LocalDate.of( 2018, Month.AUGUST, 5 ).atTime( 20, 30 ).toInstant( ZoneOffset.UTC ) ); + source.setPromotionDate( date ); + + Target target = Issue1569Mapper.INSTANCE.map( source ); + + assertThat( target.getPromotionDate() ).isEqualTo( LocalDate.of( 2018, Month.AUGUST, 5 ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Source.java new file mode 100644 index 0000000000..1be37556b9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Source.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1569.java8; + +import java.util.Date; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private Date promotionDate; + + public Date getPromotionDate() { + return promotionDate; + } + + public void setPromotionDate(Date promotionDate) { + this.promotionDate = promotionDate; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Target.java new file mode 100644 index 0000000000..d523517577 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1569/java8/Target.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1569.java8; + +import java.time.LocalDate; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private LocalDate promotionDate; + + public LocalDate getPromotionDate() { + return promotionDate; + } + + public void setPromotionDate(LocalDate promotionDate) { + this.promotionDate = promotionDate; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Issue1576Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Issue1576Mapper.java new file mode 100644 index 0000000000..a1c5a82a3b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Issue1576Mapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1576.java8; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue1576Mapper { + + Issue1576Mapper INSTANCE = Mappers.getMapper( Issue1576Mapper.class ); + + Target map( Source source ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Issue1576Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Issue1576Test.java new file mode 100644 index 0000000000..36f10eb5ad --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Issue1576Test.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1576.java8; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +@IssueKey("1576") +@WithClasses( { Issue1576Mapper.class, Source.class, Target.class }) +public class Issue1576Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + Issue1576Mapper.class + ); + + @ProcessorTest + public void testLocalDateTimeIsImported() { + + Issue1576Mapper.INSTANCE.map( new Source() ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Source.java new file mode 100644 index 0000000000..c23bb0359f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Source.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1576.java8; + +import java.util.Date; + +public class Source { + + private Date localDateTime; + private Date localDate; + private String localTime; + private Date zonedDateTime; + private Date instant; + + public Date getLocalDateTime() { + return localDateTime; + } + + public void setLocalDateTime(Date localDateTime) { + this.localDateTime = localDateTime; + } + + public Date getLocalDate() { + return localDate; + } + + public void setLocalDate(Date localDate) { + this.localDate = localDate; + } + + public String getLocalTime() { + return localTime; + } + + public void setLocalTime(String localTime) { + this.localTime = localTime; + } + + public Date getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(Date zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } + + public Date getInstant() { + return instant; + } + + public void setInstant(Date instant) { + this.instant = instant; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Target.java new file mode 100644 index 0000000000..e43ecf0737 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1576/java8/Target.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1576.java8; + +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.ZonedDateTime; + +public class Target { + + private LocalDateTime localDateTime; + private LocalDate localDate; + private LocalTime localTime; + private ZonedDateTime zonedDateTime; + private Instant instant; + + public LocalDateTime getLocalDateTime() { + return localDateTime; + } + + public void setLocalDateTime(LocalDateTime localDateTime) { + this.localDateTime = localDateTime; + } + + public LocalDate getLocalDate() { + return localDate; + } + + public void setLocalDate(LocalDate localDate) { + this.localDate = localDate; + } + + public LocalTime getLocalTime() { + return localTime; + } + + public void setLocalTime(LocalTime localTime) { + this.localTime = localTime; + } + + public ZonedDateTime getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(ZonedDateTime zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } + + public Instant getInstant() { + return instant; + } + + public void setInstant(Instant instant) { + this.instant = instant; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/Book.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/Book.java new file mode 100644 index 0000000000..bfe79c1772 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/Book.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1590; + +public class Book { + + private final String name; + + public Book(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookMapper.java new file mode 100644 index 0000000000..31acd1885a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1590; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface BookMapper { + + BookMapper INSTANCE = Mappers.getMapper( BookMapper.class ); + + Book map(Book book); + + List map(List books); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookShelf.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookShelf.java new file mode 100644 index 0000000000..056b409d4d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookShelf.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1590; + +import java.util.List; + +public class BookShelf { + private List books; + + public List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookShelfMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookShelfMapper.java new file mode 100644 index 0000000000..46f53f6469 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/BookShelfMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1590; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(uses = BookMapper.class, + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) +public interface BookShelfMapper { + + BookShelfMapper INSTANCE = Mappers.getMapper( BookShelfMapper.class ); + + BookShelf map(BookShelf bookShelf); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/Issue1590Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/Issue1590Test.java new file mode 100644 index 0000000000..0a9113797c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1590/Issue1590Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1590; + +import java.util.Arrays; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@WithClasses({ + BookMapper.class, + BookShelfMapper.class, + Book.class, + BookShelf.class +}) +@IssueKey("1590") +public class Issue1590Test { + + @ProcessorTest + public void shouldTestMappingLocalDates() { + BookShelf source = new BookShelf(); + source.setBooks( Arrays.asList( new Book("Test") ) ); + + BookShelf target = BookShelfMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getBooks() ).isNotNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1594/Issue1594Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1594/Issue1594Mapper.java new file mode 100644 index 0000000000..fbb99ed529 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1594/Issue1594Mapper.java @@ -0,0 +1,84 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1594; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1594Mapper { + + Issue1594Mapper INSTANCE = Mappers.getMapper( Issue1594Mapper.class ); + + @Mappings({ + @Mapping(target = "address.country.oid", expression = "java(dto.getFullAddress().split( \"-\" )[0])"), + @Mapping(target = "address.city.oid", expression = "java(dto.getFullAddress().split( \"-\" )[1])"), + }) + Client toClient(Dto dto); + + class Client { + private Address address; + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + } + + class Address { + + private Id country; + private Id city; + + public Id getCountry() { + return country; + } + + public void setCountry(Id country) { + this.country = country; + } + + public Id getCity() { + return city; + } + + public void setCity(Id city) { + this.city = city; + } + } + + class Id { + private String oid; + + public String getOid() { + return oid; + } + + public void setOid(String oid) { + this.oid = oid; + } + } + + class Dto { + private String fullAddress; + + public String getFullAddress() { + return fullAddress; + } + + public void setFullAddress(String fullAddress) { + this.fullAddress = fullAddress; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1594/Issue1594Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1594/Issue1594Test.java new file mode 100644 index 0000000000..0c1fed523e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1594/Issue1594Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1594; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1594") +@WithClasses({ + Issue1594Mapper.class +}) +public class Issue1594Test { + + @ProcessorTest + public void shouldGenerateCorrectMapping() { + Issue1594Mapper.Dto dto = new Issue1594Mapper.Dto(); + dto.setFullAddress( "Switzerland-Zurich" ); + + Issue1594Mapper.Client client = Issue1594Mapper.INSTANCE.toClient( dto ); + + assertThat( client ).isNotNull(); + assertThat( client.getAddress() ).isNotNull(); + assertThat( client.getAddress().getCountry() ).isNotNull(); + assertThat( client.getAddress().getCountry().getOid() ).isEqualTo( "Switzerland" ); + assertThat( client.getAddress().getCity() ).isNotNull(); + assertThat( client.getAddress().getCity().getOid() ).isEqualTo( "Zurich" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/Issue1569BuilderProvider.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/Issue1569BuilderProvider.java new file mode 100644 index 0000000000..92676f9ae0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/Issue1569BuilderProvider.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596; + +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; + +import org.mapstruct.ap.spi.BuilderInfo; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesBuilderProvider; + +public class Issue1569BuilderProvider extends ImmutablesBuilderProvider implements BuilderProvider { + + @Override + protected BuilderInfo findBuilderInfo(TypeElement typeElement) { + Name name = typeElement.getQualifiedName(); + if ( name.toString().endsWith( ".Item" ) ) { + BuilderInfo info = findBuilderInfoForImmutables( typeElement ); + if ( info != null ) { + return info; + } + } + + return super.findBuilderInfo( typeElement ); + } + + protected BuilderInfo findBuilderInfoForImmutables(TypeElement typeElement) { + TypeElement immutableElement = asImmutableElement( typeElement ); + if ( immutableElement != null ) { + return super.findBuilderInfo( immutableElement ); + } + return null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/Issue1596Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/Issue1596Test.java new file mode 100644 index 0000000000..96286aa1a1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/Issue1596Test.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596; + +import org.mapstruct.ap.spi.AccessorNamingStrategy; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy; +import org.mapstruct.ap.test.bugs._1596.domain.ImmutableItem; +import org.mapstruct.ap.test.bugs._1596.domain.Item; +import org.mapstruct.ap.test.bugs._1596.dto.ImmutableItemDTO; +import org.mapstruct.ap.test.bugs._1596.dto.ItemDTO; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.WithServiceImplementations; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@WithClasses({ + ItemMapper.class, + Item.class, + ImmutableItem.class, + ItemDTO.class, + ImmutableItemDTO.class +}) +@IssueKey("1596") +@WithServiceImplementations( { + @WithServiceImplementation( provides = BuilderProvider.class, value = Issue1569BuilderProvider.class), + @WithServiceImplementation( provides = AccessorNamingStrategy.class, value = ImmutablesAccessorNamingStrategy.class) +}) +public class Issue1596Test { + + @ProcessorTest + public void shouldIncludeBuildType() { + + ItemDTO item = ImmutableItemDTO.builder().id( "test" ).build(); + + Item target = ItemMapper.INSTANCE.map( item ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/ItemMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/ItemMapper.java new file mode 100644 index 0000000000..00f647148b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/ItemMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596; + +import org.mapstruct.Builder; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._1596.domain.Item; +import org.mapstruct.ap.test.bugs._1596.dto.ItemDTO; +import org.mapstruct.factory.Mappers; + +@Mapper( builder = @Builder) +public abstract class ItemMapper { + + public static final ItemMapper INSTANCE = Mappers.getMapper( ItemMapper.class ); + + public abstract Item map(ItemDTO itemDTO); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/domain/ImmutableItem.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/domain/ImmutableItem.java new file mode 100644 index 0000000000..ed5bb98fa1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/domain/ImmutableItem.java @@ -0,0 +1,162 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Immutable implementation of {@link Item}. + *

      + * Use the builder to create immutable instances: + * {@code ImmutableItem.builder()}. + */ +@SuppressWarnings({"all"}) +public final class ImmutableItem extends Item { + private final String id; + + private ImmutableItem(String id) { + this.id = id; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * Copy the current immutable object by setting a value for the {@link Item#getId() id} attribute. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param value A new value for id + * @return A modified copy of the {@code this} object + */ + public final ImmutableItem withId(String value) { + if (this.id == value) return this; + return new ImmutableItem(value); + } + + /** + * This instance is equal to all instances of {@code ImmutableItem} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableItem + && equalTo((ImmutableItem) another); + } + + private boolean equalTo(ImmutableItem another) { + return id.equals(another.id); + } + + /** + * Computes a hash code from attributes: {@code id}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 5381; + h += (h << 5) + id.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code Item} with attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return "Item{" + + "id=" + id + + "}"; + } + + /** + * Creates an immutable copy of a {@link Item} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable Item instance + */ + public static ImmutableItem copyOf(Item instance) { + if (instance instanceof ImmutableItem) { + return (ImmutableItem) instance; + } + return ImmutableItem.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableItem ImmutableItem}. + * @return A new ImmutableItem builder + */ + public static ImmutableItem.Builder builder() { + return new ImmutableItem.Builder(); + } + + /** + * Builds instances of type {@link ImmutableItem ImmutableItem}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code Item} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(Item instance) { + id(instance.getId()); + return this; + } + + /** + * Initializes the value for the {@link Item#getId() id} attribute. + * @param id The value for id + * @return {@code this} builder for use in a chained invocation + */ + public final Builder id(String id) { + this.id = id; + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Builds a new {@link ImmutableItem ImmutableItem}. + * @return An immutable instance of Item + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItem build() { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableItem(id); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ((initBits & INIT_BIT_ID) != 0) attributes.add("id"); + return "Cannot build Item, some of required attributes are not set " + attributes; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/domain/Item.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/domain/Item.java new file mode 100644 index 0000000000..6c5be03818 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/domain/Item.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596.domain; + +public abstract class Item { + public abstract String getId(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/dto/ImmutableItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/dto/ImmutableItemDTO.java new file mode 100644 index 0000000000..699e0f9ded --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/dto/ImmutableItemDTO.java @@ -0,0 +1,182 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596.dto; + +import java.util.ArrayList; +import java.util.List; + +/** + * Immutable implementation of {@link ItemDTO}. + *

      + * Use the builder to create immutable instances: + * {@code ImmutableItemDTO.builder()}. + */ +@SuppressWarnings({ "all" }) +public final class ImmutableItemDTO extends ItemDTO { + private final String id; + + private ImmutableItemDTO(String id) { + this.id = id; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * Copy the current immutable object by setting a value for the {@link ItemDTO#getId() id} attribute. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * + * @param value A new value for id + * + * @return A modified copy of the {@code this} object + */ + public final ImmutableItemDTO withId(String value) { + if ( this.id == value ) { + return this; + } + return new ImmutableItemDTO( value ); + } + + /** + * This instance is equal to all instances of {@code ImmutableItemDTO} that have equal attribute values. + * + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if ( this == another ) { + return true; + } + return another instanceof ImmutableItemDTO + && equalTo( (ImmutableItemDTO) another ); + } + + private boolean equalTo(ImmutableItemDTO another) { + return id.equals( another.id ); + } + + /** + * Computes a hash code from attributes: {@code id}. + * + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 5381; + h += ( h << 5 ) + id.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code ItemDTO} with attribute values. + * + * @return A string representation of the value + */ + @Override + public String toString() { + return "ItemDTO{" + + "id=" + id + + "}"; + } + + /** + * Creates an immutable copy of a {@link ItemDTO} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * + * @param instance The instance to copy + * + * @return A copied immutable ItemDTO instance + */ + public static ImmutableItemDTO copyOf(ItemDTO instance) { + if ( instance instanceof ImmutableItemDTO ) { + return (ImmutableItemDTO) instance; + } + return ImmutableItemDTO.builder() + .from( instance ) + .build(); + } + + /** + * Creates a builder for {@link ImmutableItemDTO ImmutableItemDTO}. + * + * @return A new ImmutableItemDTO builder + */ + public static ImmutableItemDTO.Builder builder() { + return new ImmutableItemDTO.Builder(); + } + + /** + * Builds instances of type {@link ImmutableItemDTO ImmutableItemDTO}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code ItemDTO} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * + * @param instance The instance from which to copy values + * + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(ItemDTO instance) { + id( instance.getId() ); + return this; + } + + /** + * Initializes the value for the {@link ItemDTO#getId() id} attribute. + * + * @param id The value for id + * + * @return {@code this} builder for use in a chained invocation + */ + public final Builder id(String id) { + this.id = id; + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Builds a new {@link ImmutableItemDTO ImmutableItemDTO}. + * + * @return An immutable instance of ItemDTO + * + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItemDTO build() { + if ( initBits != 0 ) { + throw new IllegalStateException( formatRequiredAttributesMessage() ); + } + return new ImmutableItemDTO( id ); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ( ( initBits & INIT_BIT_ID ) != 0 ) { + attributes.add( "id" ); + } + return "Cannot build ItemDTO, some of required attributes are not set " + attributes; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/dto/ItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/dto/ItemDTO.java new file mode 100644 index 0000000000..9cbed4ae54 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1596/dto/ItemDTO.java @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1596.dto; + +public abstract class ItemDTO { + public abstract String getId(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Book.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Book.java new file mode 100644 index 0000000000..0bfeb08e1b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Book.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1608; + +/** + * @author Filip Hrisafov + */ +public class Book { + + private String isbn; + + private int issueYear; + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + public int getIssueYear() { + return issueYear; + } + + public void setIssueYear(int issueYear) { + this.issueYear = issueYear; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/BookDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/BookDto.java new file mode 100644 index 0000000000..7244cc1c6a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/BookDto.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1608; + +/** + * @author Filip Hrisafov + */ +public class BookDto { + + private final String isbn; + private final int issueYear; + + public BookDto(String isbn, int issueYear) { + this.isbn = isbn; + this.issueYear = issueYear; + } + + public String getIsbn() { + return isbn; + } + + public int getIssueYear() { + return issueYear; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String isbn; + + private int issueYear; + + public String getIsbn() { + return isbn; + } + + public Builder isbn(String isbn) { + this.isbn = isbn; + return this; + } + + public int getIssueYear() { + return issueYear; + } + + public Builder setIssueYear(int issueYear) { + this.issueYear = issueYear; + return this; + } + + public BookDto build() { + return new BookDto( isbn, issueYear ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Issue1608Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Issue1608Mapper.java new file mode 100644 index 0000000000..f36f9739f9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Issue1608Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1608; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1608Mapper { + + Issue1608Mapper INSTANCE = Mappers.getMapper( Issue1608Mapper.class ); + + BookDto map(Book source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Issue1608Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Issue1608Test.java new file mode 100644 index 0000000000..528bc9b91b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1608/Issue1608Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1608; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1608") +@WithClasses({ + Issue1608Mapper.class, + Book.class, + BookDto.class +}) +public class Issue1608Test { + + @ProcessorTest + public void shouldCorrectlyUseFluentSettersStartingWithIs() { + + Book book = new Book(); + book.setIsbn( "978-3-16-148410-0" ); + book.setIssueYear( 2018 ); + BookDto bookDto = Issue1608Mapper.INSTANCE.map( book ); + + assertThat( bookDto.getIsbn() ).isEqualTo( "978-3-16-148410-0" ); + assertThat( bookDto.getIssueYear() ).isEqualTo( 2018 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Issue1648Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Issue1648Mapper.java new file mode 100644 index 0000000000..713de86997 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Issue1648Mapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1648; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface Issue1648Mapper { + + Issue1648Mapper INSTANCE = Mappers.getMapper( Issue1648Mapper.class ); + + @Mapping(target = "targetValue", source = "sourceValue") + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Issue1648Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Issue1648Test.java new file mode 100644 index 0000000000..5dfe65d77e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Issue1648Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1648; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1648") +@WithClasses({ + Issue1648Mapper.class, + Source.class, + Target.class, +}) +public class Issue1648Test { + + @ProcessorTest + public void shouldCorrectlyMarkSourceAsUsed() { + Source source = new Source(); + source.setSourceValue( "value" ); + + Target target = Issue1648Mapper.INSTANCE.map( source ); + + assertThat( target.getTargetValue() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Source.java new file mode 100644 index 0000000000..5d9f207bf0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1648; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String sourceValue; + + public String getSourceValue() { + return sourceValue; + } + + public void setSourceValue(String sourceValue) { + this.sourceValue = sourceValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Target.java new file mode 100644 index 0000000000..0225e9540f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1648/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1648; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private String targetValue; + + public String getTargetValue() { + return targetValue; + } + + public void setTargetValue(String targetValue) { + this.targetValue = targetValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/A.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/A.java new file mode 100644 index 0000000000..692f72282a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/A.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +public class A { + private B b; + + public B getB() { + return b; + } + + public void setB(B b) { + this.b = b; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/AMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/AMapper.java new file mode 100644 index 0000000000..ba6eeda861 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/AMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AMapper { + + AMapper INSTANCE = Mappers.getMapper( AMapper.class ); + + @Mapping(target = "cPrime", source = "b.c") + APrime toAPrime(A a, @MappingTarget APrime mappingTarget); + + CPrime toCPrime(C c, @MappingTarget CPrime mappingTarget); + + @Mapping(target = "cPrime", source = "b.c") + APrime toAPrime(A a); + + CPrime toCPrime(C c); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/APrime.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/APrime.java new file mode 100644 index 0000000000..625816f179 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/APrime.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +public class APrime { + + private CPrime cPrime; + + public CPrime getcPrime() { + return cPrime; + } + + public void setcPrime(CPrime cPrime) { + this.cPrime = cPrime; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/B.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/B.java new file mode 100644 index 0000000000..924858c8d3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/B.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +public class B { + private C c; + + public C getC() { + return c; + } + + public void setC(C c) { + this.c = c; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/C.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/C.java new file mode 100644 index 0000000000..dbbd74ec95 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/C.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +public class C { + + private final int value; + + public C(int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/CPrime.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/CPrime.java new file mode 100644 index 0000000000..db504189f8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/CPrime.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +public class CPrime { + + private int value; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/Issue1650Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/Issue1650Test.java new file mode 100644 index 0000000000..33237e726c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1650/Issue1650Test.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1650; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1650") +@WithClasses({ + AMapper.class, + A.class, + B.class, + C.class, + APrime.class, + CPrime.class +}) +public class Issue1650Test { + + @ProcessorTest + public void shouldCompile() { + + A a = new A(); + a.setB( new B() ); + a.getB().setC( new C( 10 ) ); + + APrime aPrime = new APrime(); + + // update mapping + AMapper.INSTANCE.toAPrime( a, aPrime ); + assertThat( aPrime.getcPrime() ).isNotNull(); + + // create mapping + APrime aPrime1 = AMapper.INSTANCE.toAPrime( a ); + assertThat( aPrime1.getcPrime() ).isNotNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Issue1660Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Issue1660Mapper.java new file mode 100644 index 0000000000..512455970c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Issue1660Mapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1660; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue1660Mapper { + + Issue1660Mapper INSTANCE = Mappers.getMapper( Issue1660Mapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Issue1660Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Issue1660Test.java new file mode 100644 index 0000000000..7de37e6b43 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Issue1660Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1660; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1660") +@WithClasses({ + Issue1660Mapper.class, + Source.class, + Target.class, +}) +public class Issue1660Test { + + @ProcessorTest + public void shouldNotUseStaticMethods() { + Source source = new Source(); + source.setValue( "source" ); + Target target = Issue1660Mapper.INSTANCE.map( source ); + + assertThat( target.getValue() ).isEqualTo( "source" ); + assertThat( Target.getStaticValue() ).isEqualTo( "targetStatic" ); + assertThat( Target.getOtherStaticValues() ).containsExactly( "targetOtherStatic" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Source.java new file mode 100644 index 0000000000..bd324f2f14 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Source.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1660; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static String getStaticValue() { + return "sourceStatic"; + } + + public String getOtherStaticValue() { + return "sourceOtherStatic"; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Target.java new file mode 100644 index 0000000000..2e2e3cd27d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1660/Target.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1660; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private static String staticValue = "targetStatic"; + private static List otherStaticValues = new ArrayList<>( Collections.singletonList( "targetOtherStatic" ) ); + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static String getStaticValue() { + return staticValue; + } + + public static void setStaticValue(String staticValue) { + Target.staticValue = staticValue; + } + + public static List getOtherStaticValues() { + return otherStaticValues; + } + + public static void addOtherStaticValue(String otherStaticValue) { + Target.otherStaticValues.add( otherStaticValue ); + } + + public static void setOtherStaticValues(List otherStaticValues) { + Target.otherStaticValues = otherStaticValues; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Issue1665Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Issue1665Mapper.java new file mode 100644 index 0000000000..1087ba4c1d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Issue1665Mapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1665; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Arne Seime + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue1665Mapper { + + Issue1665Mapper INSTANCE = Mappers.getMapper( Issue1665Mapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Issue1665Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Issue1665Test.java new file mode 100644 index 0000000000..169e01029a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Issue1665Test.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1665; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Arne Seime + */ +@IssueKey("1665") +@WithClasses({ + Issue1665Mapper.class, + Source.class, + Target.class, +}) +public class Issue1665Test { + + @ProcessorTest + public void shouldBoxIntPrimitive() { + Source source = new Source(); + List values = new ArrayList<>(); + values.add( 10 ); + source.setValue( values ); + + Target target = Issue1665Mapper.INSTANCE.map( source ); + + assertThat( target.getValue().size() ).isEqualTo( source.getValue().size() ); + assertThat( target.getValue().get( 0 ) ).isEqualTo( source.getValue().get( 0 ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Source.java new file mode 100644 index 0000000000..f89ed4436d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Source.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1665; + +import java.util.List; + +/** + * @author Arne Seime + */ +public class Source { + + private List value; + + public List getValue() { + return value; + } + + public void setValue(List value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Target.java new file mode 100644 index 0000000000..7c2cf5620d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1665/Target.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1665; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Arne Seime + */ +public class Target { + + private List value = new ArrayList<>(); + + public void addValue(int v) { + value.add( v ); + } + + public List getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Issue1681Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Issue1681Mapper.java new file mode 100644 index 0000000000..a8fcc2ec79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Issue1681Mapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1681; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1681Mapper { + + Issue1681Mapper INSTANCE = Mappers.getMapper( Issue1681Mapper.class ); + + Target update(@MappingTarget Target target, Source source); + + @Mapping(target = "builderValue", source = "value") + Target update(@MappingTarget Target.Builder targetBuilder, Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Issue1681Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Issue1681Test.java new file mode 100644 index 0000000000..901794dea0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Issue1681Test.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1681; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1681") +@WithClasses({ + Issue1681Mapper.class, + Source.class, + Target.class +}) +public class Issue1681Test { + + @ProcessorTest + public void shouldCompile() { + Target target = new Target( "before" ); + Source source = new Source(); + source.setValue( "after" ); + + Target updatedTarget = Issue1681Mapper.INSTANCE.update( target, source ); + + assertThat( updatedTarget ).isSameAs( target ); + assertThat( updatedTarget.getValue() ).isEqualTo( "after" ); + } + + @ProcessorTest + public void shouldCompileWithBuilder() { + Target.Builder targetBuilder = Target.builder(); + targetBuilder.builderValue( "before" ); + Source source = new Source(); + source.setValue( "after" ); + + Target updatedTarget = Issue1681Mapper.INSTANCE.update( targetBuilder, source ); + + assertThat( updatedTarget ).isNotNull(); + assertThat( updatedTarget.getValue() ).isEqualTo( "after" ); + assertThat( targetBuilder.getBuilderValue() ).isEqualTo( "after" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Source.java new file mode 100644 index 0000000000..384dbcca1c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1681; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Target.java new file mode 100644 index 0000000000..5a392e1968 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1681/Target.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1681; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String builderValue; + + public String getBuilderValue() { + return builderValue; + } + + public Builder builderValue(String builderValue) { + this.builderValue = builderValue; + return this; + } + + public Target build() { + return new Target( builderValue ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java new file mode 100644 index 0000000000..1d3fe69dfa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/ContactDataDTO.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import java.util.List; + +public class ContactDataDTO { + private String email; + private String phone; + private String address; + private List preferences; + private String[] settings; + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public List getPreferences() { + return preferences; + } + + public void setPreferences(List preferences) { + this.preferences = preferences; + } + + public String[] getSettings() { + return settings; + } + + public void setSettings(String[] settings) { + this.settings = settings; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java new file mode 100644 index 0000000000..eccef6df2f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/Issue1685Test.java @@ -0,0 +1,114 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1685") +@WithClasses({ + User.class, + UserDTO.class, + UserMapper.class, + ContactDataDTO.class +}) +public class Issue1685Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + UserMapper.class + ); + + @ProcessorTest + public void testSetToNullWhenNVPMSSetToNull() { + + User target = new User(); + target.setAddress( "address" ); + target.setEmail( "email" ); + target.setName( "name" ); + target.setPhone( 12345 ); + target.addPreference( "preference" ); + target.setSettings( new String[]{ "test" } ); + + UserDTO source = new UserDTO(); + source.setContactDataDTO( new ContactDataDTO() ); + source.getContactDataDTO().setAddress( "newAddress" ); + source.getContactDataDTO().setEmail( null ); + source.getContactDataDTO().setPhone( null ); + source.setName( null ); + + UserMapper.INSTANCE.updateUserFromUserDTO( source, target ); + + assertThat( target.getAddress() ).isEqualTo( "newAddress" ); + assertThat( target.getEmail() ).isNull(); + assertThat( target.getPhone() ).isNull(); + assertThat( target.getName() ).isNull(); + assertThat( target.getPreferences() ).containsOnly( "preference" ); + assertThat( target.getSettings() ).isNull(); + } + + @ProcessorTest + public void testIgnoreWhenNVPMSIgnore() { + + User target = new User(); + target.setAddress( "address" ); + target.setEmail( "email" ); + target.setName( "name" ); + target.setPhone( 12345 ); + target.addPreference( "preference" ); + target.setSettings( new String[]{ "test" } ); + + UserDTO source = new UserDTO(); + source.setContactDataDTO( new ContactDataDTO() ); + source.getContactDataDTO().setAddress( "newAddress" ); + source.getContactDataDTO().setEmail( null ); + source.getContactDataDTO().setPhone( null ); + source.setName( null ); + + UserMapper.INSTANCE.updateUserFromUserAndIgnoreDTO( source, target ); + + assertThat( target.getAddress() ).isEqualTo( "newAddress" ); + assertThat( target.getEmail() ).isEqualTo( "email" ); + assertThat( target.getPhone() ).isEqualTo( 12345 ); + assertThat( target.getName() ).isEqualTo( "name" ); + assertThat( target.getPreferences() ).containsOnly( "preference" ); + assertThat( target.getSettings() ).containsExactly( "test" ); + } + + @ProcessorTest + public void testSetToDefaultWhenNVPMSSetToDefault() { + + User target = new User(); + target.setAddress( "address" ); + target.setEmail( "email" ); + target.setName( "name" ); + target.setPhone( 12345 ); + target.addPreference( "preference" ); + target.setSettings( new String[]{ "test" } ); + + UserDTO source = new UserDTO(); + source.setContactDataDTO( new ContactDataDTO() ); + source.getContactDataDTO().setAddress( "newAddress" ); + source.getContactDataDTO().setEmail( null ); + source.getContactDataDTO().setPhone( null ); + source.setName( null ); + + UserMapper.INSTANCE.updateUserFromUserAndDefaultDTO( source, target ); + + assertThat( target.getAddress() ).isEqualTo( "newAddress" ); + assertThat( target.getEmail() ).isEqualTo( "" ); + assertThat( target.getPhone() ).isEqualTo( 0 ); + assertThat( target.getName() ).isEqualTo( "" ); + assertThat( target.getPreferences() ).containsOnly( "preference" ); + assertThat( target.getSettings() ).isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java new file mode 100644 index 0000000000..3216465fc4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/User.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import java.util.ArrayList; +import java.util.List; + +public class User { + private String name; + private String email; + private Integer phone; + private String address; + private List preferences = new ArrayList<>( ); + private String[] settings; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Integer getPhone() { + return phone; + } + + public void setPhone(Integer phone) { + this.phone = phone; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public void addPreference(String preference) { + preferences.add( preference ); + } + + public List getPreferences() { + return preferences; + } + + public String[] getSettings() { + return settings; + } + + public void setSettings(String[] settings) { + this.settings = settings; + } +} + + diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java new file mode 100644 index 0000000000..0ea035ee87 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserDTO.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +public class UserDTO { + private String name; + private ContactDataDTO contactDataDTO; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ContactDataDTO getContactDataDTO() { + return contactDataDTO; + } + + public void setContactDataDTO(ContactDataDTO contactDataDTO) { + this.contactDataDTO = contactDataDTO; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java new file mode 100644 index 0000000000..4c838a3d55 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1685/UserMapper.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1685; + +import org.mapstruct.BeanMapping; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.Mappings; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper( collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED ) +public interface UserMapper { + + UserMapper INSTANCE = Mappers.getMapper( UserMapper.class ); + + @Mappings({ + @Mapping(target = "contactDataDTO.email", source = "email" ), + @Mapping(target = "contactDataDTO.phone", source = "phone"), + @Mapping(target = "contactDataDTO.address", source = "address"), + @Mapping(target = "contactDataDTO.preferences", source = "preferences"), + @Mapping(target = "contactDataDTO.settings", source = "settings") + }) + UserDTO userToUserDTO(User user); + + @InheritInverseConfiguration + void updateUserFromUserDTO(UserDTO userDTO, @MappingTarget User user); + + @InheritInverseConfiguration + @BeanMapping( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE ) + void updateUserFromUserAndIgnoreDTO(UserDTO userDTO, @MappingTarget User user); + + @InheritInverseConfiguration + @BeanMapping( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT ) + void updateUserFromUserAndDefaultDTO(UserDTO userDTO, @MappingTarget User user); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1698/Erroneous1698Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1698/Erroneous1698Mapper.java new file mode 100644 index 0000000000..d158239778 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1698/Erroneous1698Mapper.java @@ -0,0 +1,111 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1698; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Erroneous1698Mapper { + + Erroneous1698Mapper INSTANCE = Mappers.getMapper( Erroneous1698Mapper.class ); + + Target map(Source source); + + @Mapping(target = "value", source = "source") + Cat mapToCat(String source); + + @Mapping(target = "value", source = "source") + Dog mapToDog(String source); + + class Source { + + private String cat; + private String dog; + private String rabbit; + + public String getCat() { + return cat; + } + + public void setCat(String cat) { + this.cat = cat; + } + + public String getDog() { + return dog; + } + + public void setDog(String dog) { + this.dog = dog; + } + + public String getRabbit() { + return rabbit; + } + + public void setRabbit(String rabbit) { + this.rabbit = rabbit; + } + } + + class Target { + + private Cat cat; + private Dog dog; + private Rabbit rabbit; + + public Cat getCat() { + return cat; + } + + public void setCat(Cat cat) { + this.cat = cat; + } + + public Dog getDog() { + return dog; + } + + public void setDog(Dog dog) { + this.dog = dog; + } + + public Rabbit getRabbit() { + return rabbit; + } + + public void setRabbit(Rabbit rabbit) { + this.rabbit = rabbit; + } + } + + class Animal { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Cat extends Animal { + + } + + class Dog extends Animal { + + } + + class Rabbit extends Animal { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1698/Issue1698Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1698/Issue1698Test.java new file mode 100644 index 0000000000..c5af6d923f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1698/Issue1698Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1698; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +@IssueKey("1698") +@WithClasses(Erroneous1698Mapper.class) +public class Issue1698Test { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = Erroneous1698Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + message = "Can't map property \"String rabbit\" to \"Erroneous1698Mapper.Rabbit rabbit\". " + + "Consider to declare/implement a mapping method: \"Erroneous1698Mapper.Rabbit map(String value)\".") + }) + + public void testErrorMessage() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1707/Converter.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1707/Converter.java new file mode 100644 index 0000000000..45659b9d6f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1707/Converter.java @@ -0,0 +1,89 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1707; + +import java.util.Set; +import java.util.stream.Stream; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; + +@Mapper +public abstract class Converter { + + public abstract Set convert(Stream source); + + public abstract Target[] convertArray(Stream source); + + @Mapping( target = "custom", ignore = true ) + public abstract Target convert(Source source); + + @AfterMapping + public void addCustomValue(@MappingTarget Set targetList) { + targetList.forEach( t -> t.custom = true ); + } + + @AfterMapping + public void addCustomValue(@MappingTarget Target[] targetArray) { + for ( Target target : targetArray ) { + target.custom = true; + } + } + + public static final class Source { + private String text; + private int number; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + } + + public static class Target { + private String text; + private int number; + private boolean custom; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public boolean isCustom() { + return custom; + } + + public void setCustom(boolean custom) { + this.custom = custom; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1707/Issue1707Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1707/Issue1707Test.java new file mode 100644 index 0000000000..9798ea1bb6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1707/Issue1707Test.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1707; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +@IssueKey("1707") +@WithClasses({ + Converter.class +}) +public class Issue1707Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + Converter.class + ); + + @ProcessorTest + public void codeShouldBeGeneratedCorrectly() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1714/Issue1714Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1714/Issue1714Mapper.java new file mode 100644 index 0000000000..3985606d94 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1714/Issue1714Mapper.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1714; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue1714Mapper { + + Issue1714Mapper INSTANCE = Mappers.getMapper( Issue1714Mapper.class ); + + @Mapping(target = "seasonNumber", source = "programInstance", qualifiedByName = "getSeasonNumber") + OfferEntity map(OnDemand offerStatusDTO); + + @Named("getTitle") + default String mapTitle(Program programInstance) { + return "dont care"; + } + + @Named("getSeasonNumber") + default Integer mapSeasonNumber(Program programInstance) { + return 1; + } + + class OfferEntity { + + private String seasonNumber; + + public String getSeasonNumber() { + return seasonNumber; + } + + public void setSeasonNumber(String seasonNumber) { + this.seasonNumber = seasonNumber; + } + + } + + class OnDemand { + + private Program programInstance; + + public Program getProgramInstance() { + return programInstance; + } + + public void setProgramInstance(Program programInstance) { + this.programInstance = programInstance; + } + } + + class Program { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1714/Issue1714Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1714/Issue1714Test.java new file mode 100644 index 0000000000..4a2e42ad61 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1714/Issue1714Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1714; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1714") +@WithClasses({ + Issue1714Mapper.class +}) +public class Issue1714Test { + + @ProcessorTest + public void codeShouldBeGeneratedCorrectly() { + + Issue1714Mapper.OnDemand source = new Issue1714Mapper.OnDemand(); + source.setProgramInstance( new Issue1714Mapper.Program() ); + + Issue1714Mapper.OfferEntity result = Issue1714Mapper.INSTANCE.map( source ); + + assertThat( result.getSeasonNumber() ).isEqualTo( "1" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Issue1719Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Issue1719Mapper.java new file mode 100644 index 0000000000..f4ac6978f6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Issue1719Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1719; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue1719Mapper { + + Issue1719Mapper INSTANCE = Mappers.getMapper( Issue1719Mapper.class ); + + @Mapping(target = "targetElements", source = "sourceElements") + void map(Source source, @MappingTarget Target target); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Issue1719Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Issue1719Test.java new file mode 100644 index 0000000000..7a8665e49f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Issue1719Test.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1719; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +@IssueKey("1719") +@WithClasses({ + Source.class, + SourceElement.class, + Target.class, + TargetElement.class +}) +public class Issue1719Test { + + /** + * For adder methods MapStuct cannot generate an update method. MapStruct would cannot know how to remove objects + * from the child-parent relation. It cannot even assume that the collection can be cleared at forehand. + * Therefore, the only sensible choice is for MapStruct to create a create method for the target elements. + */ + @ProcessorTest + @WithClasses(Issue1719Mapper.class) + public void testShouldGiveNoErrorMessage() { + Source source = new Source(); + source.getSourceElements().add( new SourceElement( 1, "jim" ) ); + source.getSourceElements().add( new SourceElement( 2, "alice" ) ); + + Target target = new Target(); + TargetElement bob = new TargetElement( 1, "bob" ); + target.addTargetElement( bob ); + TargetElement louise = new TargetElement( 3, "louise" ); + target.addTargetElement( louise ); + + Issue1719Mapper.INSTANCE.map( source, target ); + + assertThat( target.getTargetElements() ).hasSize( 3 ); + assertThat( target.getTargetElements() ) + .extracting( TargetElement::getId, TargetElement::getName ) + .containsOnly( + tuple( 1, "bob" ), + tuple( 2, "alice" ), + tuple( 3, "louise" ) + ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Source.java new file mode 100644 index 0000000000..f3e6b1ea20 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Source.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1719; + +import java.util.HashSet; +import java.util.Set; + +public class Source { + + private Set sourceElements = new HashSet<>(); + + public Set getSourceElements() { + return sourceElements; + } + + public void setSourceElements(Set sourceElements) { + this.sourceElements = sourceElements; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/SourceElement.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/SourceElement.java new file mode 100644 index 0000000000..fbfe00e829 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/SourceElement.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1719; + +import java.util.Objects; + +public class SourceElement { + + private int id; + private String name; + + public SourceElement(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SourceElement that = (SourceElement) o; + return id == that.id; + } + + @Override + public int hashCode() { + return Objects.hash( id ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Target.java new file mode 100644 index 0000000000..9d14a9a143 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/Target.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1719; + +import java.util.HashSet; +import java.util.Set; + +public class Target { + + private Set targetElements = new HashSet<>(); + + public Set getTargetElements() { + return targetElements; + } + + public void setTargetElements(Set targetElements) { + this.targetElements = targetElements; + } + + public TargetElement addTargetElement(TargetElement element) { + element.updateTarget( this ); + getTargetElements().add( element ); + return element; + } + + public TargetElement removeTargetElement(TargetElement element) { + element.updateTarget( null ); + getTargetElements().remove( element ); + return element; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/TargetElement.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/TargetElement.java new file mode 100644 index 0000000000..92d1970af2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1719/TargetElement.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1719; + +import java.util.Objects; + +public class TargetElement { + + private int id; + private String name; + private Target target; + + public TargetElement() { + } + + public TargetElement(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Target getTarget() { + return target; + } + + /** + * intentionally not a setter, to not further complicate this test case. + * + * @param target + */ + public void updateTarget(Target target) { + this.target = target; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + TargetElement that = (TargetElement) o; + return id == that.id; + } + + @Override + public int hashCode() { + return Objects.hash( id ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Issue1738Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Issue1738Mapper.java new file mode 100644 index 0000000000..79147f2247 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Issue1738Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1738; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1738Mapper { + + Issue1738Mapper INSTANCE = Mappers.getMapper( Issue1738Mapper.class ); + + @Mapping(target = "value", source = "nested.value") + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Issue1738Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Issue1738Test.java new file mode 100644 index 0000000000..e0755312fa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Issue1738Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1738; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1738") +@WithClasses({ + Issue1738Mapper.class, + Source.class, + Target.class +}) +public class Issue1738Test { + + @ProcessorTest + public void shouldGenerateCorrectSourceNestedMapping() { + Source source = new Source(); + Source.Nested nested = new Source.Nested<>(); + source.setNested( nested ); + nested.setValue( 100L ); + + Target target = Issue1738Mapper.INSTANCE.map( source ); + + assertThat( target.getValue() ).isEqualTo( 100L ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Source.java new file mode 100644 index 0000000000..7f67c6db6d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Source.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1738; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private Nested nested; + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + + public static class Nested { + + private T value; + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Target.java new file mode 100644 index 0000000000..931ccb85b7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1738/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1738; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private Number value; + + public Number getValue() { + return value; + } + + public void setValue(Number value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Issue1742Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Issue1742Mapper.java new file mode 100644 index 0000000000..55b5dd03c4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Issue1742Mapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1742; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1742Mapper { + + void update(@MappingTarget Target target, Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Issue1742Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Issue1742Test.java new file mode 100644 index 0000000000..6c64e0c261 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Issue1742Test.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1742; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1742") +@WithClasses( { + Issue1742Mapper.class, + NestedSource.class, + NestedTarget.class, + Source.class, + Target.class, +} ) +public class Issue1742Test { + + @ProcessorTest + public void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/NestedSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/NestedSource.java new file mode 100644 index 0000000000..9506c946b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/NestedSource.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1742; + +/** + * @author Filip Hrisafov + */ +public class NestedSource { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/NestedTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/NestedTarget.java new file mode 100644 index 0000000000..82dbbd91b6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/NestedTarget.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1742; + +/** + * @author Filip Hrisafov + */ +public class NestedTarget { + + private String value; + + public NestedTarget() { + + } + + public NestedTarget(Builder builder) { + this.value = getValue(); + } + + public static Builder builder() { + return new Builder(); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static class Builder { + + private String value; + + public Builder value(String value) { + this.value = value; + return this; + } + + public NestedTarget create() { + return new NestedTarget(this); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Source.java new file mode 100644 index 0000000000..e6a7b54c86 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1742; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private NestedSource nested; + + public NestedSource getNested() { + return nested; + } + + public void setNested(NestedSource nested) { + this.nested = nested; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Target.java new file mode 100644 index 0000000000..ab320b606f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1742/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1742; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private NestedTarget nested; + + public NestedTarget getNested() { + return nested; + } + + public void setNested(NestedTarget nested) { + this.nested = nested; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Holder.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Holder.java new file mode 100644 index 0000000000..cd35297d73 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Holder.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1751; + +/** + * @author Filip Hrisafov + */ +public class Holder { + + private final T value; + + public Holder(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + // If empty is considered as a builder creation method, this method would be the build method and would + // lead to a stackoverflow + @SuppressWarnings("unused") + public Holder duplicate() { + return new Holder<>( value ); + } + + // This method should not be considered as builder creation method + @SuppressWarnings("unused") + public static Holder empty() { + return new Holder<>( null ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Issue1751Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Issue1751Mapper.java new file mode 100644 index 0000000000..62fb66dc0b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Issue1751Mapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1751; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1751Mapper { + + Issue1751Mapper INSTANCE = Mappers.getMapper( Issue1751Mapper.class ); + + Target map(Source source); + + default Holder mapToHolder(Source source) { + return new Holder<>( this.map( source ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Issue1751Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Issue1751Test.java new file mode 100644 index 0000000000..e35424761a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Issue1751Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1751; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1772") +@WithClasses({ + Holder.class, + Issue1751Mapper.class, + Source.class, + Target.class +}) +public class Issue1751Test { + + @ProcessorTest + public void name() { + Source source = new Source(); + source.setValue( "some value" ); + + Holder targetHolder = Issue1751Mapper.INSTANCE.mapToHolder( source ); + + assertThat( targetHolder.getValue() ) + .extracting( Target::getValue ) + .isEqualTo( "some value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Source.java new file mode 100644 index 0000000000..d69e688d79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1751; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Target.java new file mode 100644 index 0000000000..a6b2ca91b5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1751/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1751; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Issue1772Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Issue1772Mapper.java new file mode 100644 index 0000000000..867385ce25 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Issue1772Mapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1772; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface Issue1772Mapper { + + Issue1772Mapper INSTANCE = Mappers.getMapper( Issue1772Mapper.class ); + + @Mapping(target = "nestedTarget.doubleNestedTarget", source = "nestedSource.doublyNestedSourceField" ) + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Issue1772Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Issue1772Test.java new file mode 100644 index 0000000000..e05938e2f9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Issue1772Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1772; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@IssueKey("1772") +@WithClasses({ + Issue1772Mapper.class, + Source.class, + Target.class, +}) +public class Issue1772Test { + + @ProcessorTest + public void shouldCorrectlyMarkSourceAsUsed() { + + Source source = new Source(); + source.setNestedSource( new Source.NestedSource() ); + source.getNestedSource().setDoublyNestedSourceField( 5d ); + + Target target = Issue1772Mapper.INSTANCE.map( source ); + + assertThat( target.getNestedTarget().getDoubleNestedTarget() ).isEqualTo( 5d ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Source.java new file mode 100644 index 0000000000..076ae8a410 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Source.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1772; + +/** + * @author Sjaak Derksen + */ +public class Source { + + private NestedSource nestedSource; + + public NestedSource getNestedSource() { + return nestedSource; + } + + public void setNestedSource(NestedSource nestedSource) { + this.nestedSource = nestedSource; + } + + public static class NestedSource { + + private double doublyNestedSourceField; + + public double getDoublyNestedSourceField() { + return doublyNestedSourceField; + } + + public void setDoublyNestedSourceField(double doublyNestedSourceField) { + this.doublyNestedSourceField = doublyNestedSourceField; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Target.java new file mode 100644 index 0000000000..6ad876acd1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1772/Target.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1772; + +/** + * @author Sjaak Derksen + */ +public class Target { + + private NestedTarget nestedTarget; + + public NestedTarget getNestedTarget() { + return nestedTarget; + } + + public void setNestedTarget(NestedTarget nestedTarget) { + this.nestedTarget = nestedTarget; + } + + public static class NestedTarget { + + private double doubleNestedTarget; + + public double getDoubleNestedTarget() { + return doubleNestedTarget; + } + + public void setDoubleNestedTarget(double doubleNestedTarget) { + this.doubleNestedTarget = doubleNestedTarget; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1788/Issue1788Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1788/Issue1788Mapper.java new file mode 100644 index 0000000000..d265f00192 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1788/Issue1788Mapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1788; + +import org.mapstruct.Mapper; + +@Mapper +public interface Issue1788Mapper { + + Container toContainer(Container.Type type); + + class Container { + public enum Type { + ONE, TWO + } + + //CHECKSTYLE:OFF + public Type type; + //CHECKSTYLE:ON + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1788/Issue1788Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1788/Issue1788Test.java new file mode 100644 index 0000000000..bd5d687ae0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1788/Issue1788Test.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1788; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@IssueKey( "1788" ) +@WithClasses( + Issue1788Mapper.class +) +public class Issue1788Test { + + @ProcessorTest + public void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Config.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Config.java new file mode 100644 index 0000000000..41fe78a0d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Config.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1790; + +import org.mapstruct.MapperConfig; +import org.mapstruct.NullValueCheckStrategy; + +/** + * @author Filip Hrisafov + */ +@MapperConfig(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface Issue1790Config { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Mapper.java new file mode 100644 index 0000000000..72330b7356 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1790; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(config = Issue1790Config.class, nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface Issue1790Mapper { + + Issue1790Mapper INSTANCE = Mappers.getMapper( Issue1790Mapper.class ); + + void toExistingCar(@MappingTarget Target target, Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Test.java new file mode 100644 index 0000000000..c92d240cbf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Issue1790Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1790; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1790") +@WithClasses({ + Issue1790Config.class, + Issue1790Mapper.class, + Source.class, + Target.class, +}) +public class Issue1790Test { + + @ProcessorTest + public void shouldProperlyApplyNullValuePropertyMappingStrategyWhenInheriting() { + Target target = new Target(); + target.setName( "My name is set" ); + + Source source = new Source(); + + Issue1790Mapper.INSTANCE.toExistingCar( target, source ); + + assertThat( target.getName() ).isEqualTo( "My name is set" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Source.java new file mode 100644 index 0000000000..af6c94b279 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1790; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Target.java new file mode 100644 index 0000000000..facbbaf48c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1790/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1790; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Customer.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Customer.java new file mode 100644 index 0000000000..1d7dce9aa2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Customer.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1797; + +import java.util.EnumSet; + +/** + * @author Filip Hrisafov + */ +public class Customer { + + public enum Type { + ONE, TWO + } + + private final EnumSet types; + + public Customer(EnumSet types) { + this.types = types; + } + + public EnumSet getTypes() { + return types; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/CustomerDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/CustomerDto.java new file mode 100644 index 0000000000..fd51ddc6cd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/CustomerDto.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1797; + +import java.util.EnumSet; + +/** + * @author Filip Hrisafov + */ +public class CustomerDto { + + public enum Type { + ONE, TWO + } + + private EnumSet types; + + public EnumSet getTypes() { + return types; + } + + public void setTypes(EnumSet types) { + this.types = types; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Issue1797Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Issue1797Mapper.java new file mode 100644 index 0000000000..f5a0e4162a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Issue1797Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1797; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1797Mapper { + + Issue1797Mapper INSTANCE = Mappers.getMapper( Issue1797Mapper.class ); + + CustomerDto map(Customer customer); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Issue1797Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Issue1797Test.java new file mode 100644 index 0000000000..bd9fcb92e0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1797/Issue1797Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1797; + +import java.util.EnumSet; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1797") +@WithClasses({ + Customer.class, + CustomerDto.class, + Issue1797Mapper.class +}) +public class Issue1797Test { + + @ProcessorTest + public void shouldCorrectlyMapEnumSetToEnumSet() { + + Customer customer = new Customer( EnumSet.of( Customer.Type.ONE ) ); + + CustomerDto customerDto = Issue1797Mapper.INSTANCE.map( customer ); + + assertThat( customerDto.getTypes() ).containsExactly( CustomerDto.Type.ONE ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Issue1799Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Issue1799Mapper.java new file mode 100644 index 0000000000..7b695dd146 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Issue1799Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1799; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1799Mapper { + + Issue1799Mapper INSTANCE = Mappers.getMapper( Issue1799Mapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Issue1799Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Issue1799Test.java new file mode 100644 index 0000000000..b3234cbcfc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Issue1799Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1799; + +import java.util.Date; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue1799Mapper.class, + Source.class, + Target.class, +}) +@IssueKey("1799") +public class Issue1799Test { + + @ProcessorTest + public void fluentJavaBeanStyleSettersShouldWork() { + Target target = Issue1799Mapper.INSTANCE.map( new Source( new Date( 150 ), "Switzerland" ) ); + + assertThat( target.getSettlementDate() ).isEqualTo( new Date( 150 ) ); + assertThat( target.getGetawayLocation() ).isEqualTo( "Switzerland" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Source.java new file mode 100644 index 0000000000..dc7153a2f2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Source.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1799; + +import java.util.Date; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final Date settlementDate; + private final String getawayLocation; + + public Source(Date settlementDate, String getawayLocation) { + this.settlementDate = settlementDate; + this.getawayLocation = getawayLocation; + } + + public Date getSettlementDate() { + return settlementDate; + } + + public String getGetawayLocation() { + return getawayLocation; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Target.java new file mode 100644 index 0000000000..992e3d2286 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1799/Target.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1799; + +import java.util.Date; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final Date settlementDate; + private final String getawayLocation; + + public Target(Builder builder) { + this.settlementDate = builder.settlementDate; + this.getawayLocation = builder.getawayLocation; + } + + public Date getSettlementDate() { + return settlementDate; + } + + public String getGetawayLocation() { + return getawayLocation; + } + + public static Target.Builder builder() { + return new Builder(); + } + + public static class Builder { + + private Date settlementDate; + private String getawayLocation; + + public Builder settlementDate(Date settlementDate) { + this.settlementDate = settlementDate; + return this; + } + + public Builder getawayLocation(String getawayLocation) { + this.getawayLocation = getawayLocation; + return this; + } + + public Target build() { + return new Target( this ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/Issue1801BuilderProvider.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/Issue1801BuilderProvider.java new file mode 100644 index 0000000000..d8b5ccdbb3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/Issue1801BuilderProvider.java @@ -0,0 +1,96 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801; + +import java.util.List; +import java.util.Objects; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; + +import org.mapstruct.ap.spi.BuilderInfo; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesBuilderProvider; + +/** + * @author Zhizhi Deng + */ +public class Issue1801BuilderProvider extends ImmutablesBuilderProvider implements BuilderProvider { + + @Override + protected BuilderInfo findBuilderInfo(TypeElement typeElement) { + Name name = typeElement.getQualifiedName(); + if ( name.toString().endsWith( ".Item" ) ) { + BuilderInfo info = findBuilderInfoFromInnerBuilderClass( typeElement ); + if ( info != null ) { + return info; + } + } + return super.findBuilderInfo( typeElement ); + } + + /** + * Looks for inner builder class in the Immutable interface / abstract class. + * + * The inner builder class should be be declared with the following line + * + *

      +     *     public static Builder() extends ImmutableItem.Builder { }
      +     * 
      + * + * The Immutable instance should be created with the following line + * + *
      +     *     new Item.Builder().withId("123").build();
      +     * 
      + * + * @see org.mapstruct.ap.test.bugs._1801.domain.Item + * + * @param typeElement + * @return + */ + private BuilderInfo findBuilderInfoFromInnerBuilderClass(TypeElement typeElement) { + if ( shouldIgnore( typeElement ) ) { + return null; + } + + List innerTypes = ElementFilter.typesIn( typeElement.getEnclosedElements() ); + ExecutableElement defaultConstructor = innerTypes.stream() + .filter( this::isBuilderCandidate ) + .map( this::getEmptyArgPublicConstructor ) + .filter( Objects::nonNull ) + .findAny() + .orElse( null ); + + if ( defaultConstructor != null ) { + return new BuilderInfo.Builder() + .builderCreationMethod( defaultConstructor ) + .buildMethod( findBuildMethods( (TypeElement) defaultConstructor.getEnclosingElement(), typeElement ) ) + .build(); + } + return null; + } + + private boolean isBuilderCandidate(TypeElement innerType ) { + TypeElement outerType = (TypeElement) innerType.getEnclosingElement(); + String packageName = this.elementUtils.getPackageOf( outerType ).getQualifiedName().toString(); + Name outerSimpleName = outerType.getSimpleName(); + String builderClassName = packageName + ".Immutable" + outerSimpleName + ".Builder"; + return innerType.getSimpleName().contentEquals( "Builder" ) + && getTypeElement( innerType.getSuperclass() ).getQualifiedName().contentEquals( builderClassName ) + && innerType.getModifiers().contains( Modifier.PUBLIC ); + } + + private ExecutableElement getEmptyArgPublicConstructor(TypeElement builderType) { + return ElementFilter.constructorsIn( builderType.getEnclosedElements() ).stream() + .filter( c -> c.getParameters().isEmpty() ) + .filter( c -> c.getModifiers().contains( Modifier.PUBLIC ) ) + .findAny() + .orElse( null ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/Issue1801Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/Issue1801Test.java new file mode 100644 index 0000000000..40b9515305 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/Issue1801Test.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801; + +import org.mapstruct.ap.spi.AccessorNamingStrategy; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy; +import org.mapstruct.ap.test.bugs._1801.domain.ImmutableItem; +import org.mapstruct.ap.test.bugs._1801.domain.Item; +import org.mapstruct.ap.test.bugs._1801.dto.ImmutableItemDTO; +import org.mapstruct.ap.test.bugs._1801.dto.ItemDTO; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.WithServiceImplementations; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Zhizhi Deng + */ +@WithClasses({ + ItemMapper.class, + Item.class, + ImmutableItem.class, + ItemDTO.class, + ImmutableItemDTO.class +}) +@IssueKey("1801") +@WithServiceImplementations( { + @WithServiceImplementation( provides = BuilderProvider.class, value = Issue1801BuilderProvider.class), + @WithServiceImplementation( provides = AccessorNamingStrategy.class, value = ImmutablesAccessorNamingStrategy.class) +}) +public class Issue1801Test { + + @ProcessorTest + public void shouldIncludeBuilderType() { + + ItemDTO item = ImmutableItemDTO.builder().id( "test" ).build(); + + Item target = ItemMapper.INSTANCE.map( item ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/ItemMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/ItemMapper.java new file mode 100644 index 0000000000..f43bf12ca2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/ItemMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801; + +import org.mapstruct.Builder; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._1801.domain.Item; +import org.mapstruct.ap.test.bugs._1801.dto.ItemDTO; +import org.mapstruct.factory.Mappers; + +/** + * @author Zhizhi Deng + */ +@Mapper( builder = @Builder) +public abstract class ItemMapper { + + public static final ItemMapper INSTANCE = Mappers.getMapper( ItemMapper.class ); + + public abstract Item map(ItemDTO itemDTO); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/domain/ImmutableItem.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/domain/ImmutableItem.java new file mode 100644 index 0000000000..d5b39cf4dc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/domain/ImmutableItem.java @@ -0,0 +1,154 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801.domain; + +import java.util.ArrayList; +import java.util.List; + +/** + * Immutable implementation of {@link Item}. + *

      + * Superclass should expose a static subclass of the Builder to create immutable instance + * {@code public static Builder extends ImmutableItem.Builder}. + * + * @author Zhizhi Deng + */ +@SuppressWarnings({"all"}) +public final class ImmutableItem extends Item { + private final String id; + + private ImmutableItem(String id) { + this.id = id; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * Copy the current immutable object by setting a value for the {@link Item#getId() id} attribute. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param value A new value for id + * @return A modified copy of the {@code this} object + */ + public final ImmutableItem withId(String value) { + if (this.id == value) return this; + return new ImmutableItem(value); + } + + /** + * This instance is equal to all instances of {@code ImmutableItem} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableItem + && equalTo((ImmutableItem) another); + } + + private boolean equalTo(ImmutableItem another) { + return id.equals(another.id); + } + + /** + * Computes a hash code from attributes: {@code id}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 5381; + h += (h << 5) + id.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code Item} with attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return "Item{" + + "id=" + id + + "}"; + } + + /** + * Creates an immutable copy of a {@link Item} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable Item instance + */ + public static ImmutableItem copyOf(Item instance) { + if (instance instanceof ImmutableItem) { + return (ImmutableItem) instance; + } + return new Builder() + .from(instance) + .build(); + } + + /** + * Builds instances of type {@link ImmutableItem ImmutableItem}. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + + Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code Item} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(Item instance) { + id(instance.getId()); + return this; + } + + /** + * Initializes the value for the {@link Item#getId() id} attribute. + * @param id The value for id + * @return {@code this} builder for use in a chained invocation + */ + public final Builder id(String id) { + this.id = id; + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Builds a new {@link ImmutableItem ImmutableItem}. + * @return An immutable instance of Item + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItem build() { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableItem(id); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ((initBits & INIT_BIT_ID) != 0) attributes.add("id"); + return "Cannot build Item, some of required attributes are not set " + attributes; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/domain/Item.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/domain/Item.java new file mode 100644 index 0000000000..e0f3899077 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/domain/Item.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801.domain; + +/** + * @author Zhizhi Deng + */ +public abstract class Item { + public abstract String getId(); + + public static class Builder extends ImmutableItem.Builder { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/dto/ImmutableItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/dto/ImmutableItemDTO.java new file mode 100644 index 0000000000..bf10721aa1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/dto/ImmutableItemDTO.java @@ -0,0 +1,184 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801.dto; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * Immutable implementation of {@link ItemDTO}. + *

      + * Use the builder to create immutable instances: + * {@code ImmutableItemDTO.builder()}. + * + * @author Zhizhi Deng + */ +public final class ImmutableItemDTO extends ItemDTO { + private final String id; + + private ImmutableItemDTO(String id) { + this.id = id; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * Copy the current immutable object by setting a value for the {@link ItemDTO#getId() id} attribute. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * + * @param value A new value for id + * + * @return A modified copy of the {@code this} object + */ + public ImmutableItemDTO withId(String value) { + if ( Objects.equals( this.id, value ) ) { + return this; + } + return new ImmutableItemDTO( value ); + } + + /** + * This instance is equal to all instances of {@code ImmutableItemDTO} that have equal attribute values. + * + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if ( this == another ) { + return true; + } + return another instanceof ImmutableItemDTO + && equalTo( (ImmutableItemDTO) another ); + } + + private boolean equalTo(ImmutableItemDTO another) { + return id.equals( another.id ); + } + + /** + * Computes a hash code from attributes: {@code id}. + * + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 5381; + h += ( h << 5 ) + id.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code ItemDTO} with attribute values. + * + * @return A string representation of the value + */ + @Override + public String toString() { + return "ItemDTO{" + + "id=" + id + + "}"; + } + + /** + * Creates an immutable copy of a {@link ItemDTO} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * + * @param instance The instance to copy + * + * @return A copied immutable ItemDTO instance + */ + public static ImmutableItemDTO copyOf(ItemDTO instance) { + if ( instance instanceof ImmutableItemDTO ) { + return (ImmutableItemDTO) instance; + } + return ImmutableItemDTO.builder() + .from( instance ) + .build(); + } + + /** + * Creates a builder for {@link ImmutableItemDTO ImmutableItemDTO}. + * + * @return A new ImmutableItemDTO builder + */ + public static ImmutableItemDTO.Builder builder() { + return new ImmutableItemDTO.Builder(); + } + + /** + * Builds instances of type {@link ImmutableItemDTO ImmutableItemDTO}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static final class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + + private Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code ItemDTO} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * + * @param instance The instance from which to copy values + * + * @return {@code this} builder for use in a chained invocation + */ + public Builder from(ItemDTO instance) { + id( instance.getId() ); + return this; + } + + /** + * Initializes the value for the {@link ItemDTO#getId() id} attribute. + * + * @param id The value for id + * + * @return {@code this} builder for use in a chained invocation + */ + public Builder id(String id) { + this.id = id; + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Builds a new {@link ImmutableItemDTO ImmutableItemDTO}. + * + * @return An immutable instance of ItemDTO + * + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItemDTO build() { + if ( initBits != 0 ) { + throw new IllegalStateException( formatRequiredAttributesMessage() ); + } + return new ImmutableItemDTO( id ); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ( ( initBits & INIT_BIT_ID ) != 0 ) { + attributes.add( "id" ); + } + return "Cannot build ItemDTO, some of required attributes are not set " + attributes; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/dto/ItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/dto/ItemDTO.java new file mode 100644 index 0000000000..1b8866b5ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1801/dto/ItemDTO.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1801.dto; + +/** + * @author Zhizhi Deng + */ +public abstract class ItemDTO { + public abstract String getId(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1821/Issue1821Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1821/Issue1821Mapper.java new file mode 100644 index 0000000000..406fa7b71b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1821/Issue1821Mapper.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1821; + +import org.mapstruct.BeanMapping; +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue1821Mapper { + + Issue1821Mapper INSTANCE = Mappers.getMapper( Issue1821Mapper.class ); + + @BeanMapping( resultType = Target.class ) + Target map(Source source); + + @InheritConfiguration( name = "map" ) + ExtendedTarget mapExtended(Source source); + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class ExtendedTarget extends Target { + } + + class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1821/Issue1821Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1821/Issue1821Test.java new file mode 100644 index 0000000000..865ef8f6c1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1821/Issue1821Test.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1821; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@IssueKey("1797") +@WithClasses( Issue1821Mapper.class ) +public class Issue1821Test { + + @ProcessorTest + public void shouldNotGiveNullPtr() { + Issue1821Mapper.INSTANCE.map( new Issue1821Mapper.Source( "test" ) ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Issue1826Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Issue1826Mapper.java new file mode 100644 index 0000000000..126837cbfa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Issue1826Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1826; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue1826Mapper { + + Issue1826Mapper INSTANCE = Mappers.getMapper( Issue1826Mapper.class ); + + @Mapping(target = "content", source = "sourceChild.content") + Target sourceAToTarget(SourceParent sourceParent); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Issue1826Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Issue1826Test.java new file mode 100644 index 0000000000..be22569e5b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Issue1826Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1826; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1826") +@WithClasses({ + SourceParent.class, + SourceChild.class, + Target.class, + Issue1826Mapper.class +}) +public class Issue1826Test { + + @ProcessorTest + public void testNestedPropertyMappingChecksForNull() { + SourceParent sourceParent = new SourceParent(); + sourceParent.setSourceChild( null ); + + Target result = Issue1826Mapper.INSTANCE.sourceAToTarget( sourceParent ); + assertThat( result.getContent() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/SourceChild.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/SourceChild.java new file mode 100644 index 0000000000..4243d444eb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/SourceChild.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1826; + +public class SourceChild { + + private String content; + private Boolean hasContent = false; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + hasContent = true; + } + + public Boolean hasContent() { + return hasContent; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/SourceParent.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/SourceParent.java new file mode 100644 index 0000000000..65f737d15d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/SourceParent.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1826; + +public class SourceParent { + + private SourceChild sourceChild; + private Boolean hasSourceChild = false; + + public SourceChild getSourceChild() { + return sourceChild; + } + + public void setSourceChild(SourceChild sourceChild) { + this.sourceChild = sourceChild; + this.hasSourceChild = true; + } + + public Boolean hasSourceChild() { + return hasSourceChild; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Target.java new file mode 100644 index 0000000000..9d2ec717f3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1826/Target.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1826; + +public class Target { + + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/CompleteAddress.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/CompleteAddress.java new file mode 100644 index 0000000000..7af21d26b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/CompleteAddress.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +public class CompleteAddress { + + private String lineOne; + private String lineTwo; + private String city; + private String country; + + public String getLineOne() { + return lineOne; + } + + public void setLineOne(String lineOne) { + this.lineOne = lineOne; + } + + public String getLineTwo() { + return lineTwo; + } + + public void setLineTwo(String lineTwo) { + this.lineTwo = lineTwo; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Employee.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Employee.java new file mode 100644 index 0000000000..e635cd16d2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Employee.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +public class Employee { + + private String name; + private GeneralAddress generalAddress; + private SpecialAddress specialAddress; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public GeneralAddress getGeneralAddress() { + return generalAddress; + } + + public void setGeneralAddress(GeneralAddress generalAddress) { + this.generalAddress = generalAddress; + } + + public SpecialAddress getSpecialAddress() { + return specialAddress; + } + + public void setSpecialAddress(SpecialAddress specialAddress) { + this.specialAddress = specialAddress; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/FirstMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/FirstMapper.java new file mode 100644 index 0000000000..9d4540c70b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/FirstMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface FirstMapper { + + FirstMapper INSTANCE = Mappers.getMapper( FirstMapper.class ); + + @Mapping(target = "completeAddress.lineOne", source = "specialAddress.line1") + @Mapping(target = "completeAddress.lineTwo", source = "specialAddress.line2") + @Mapping(target = "completeAddress.city", source = "generalAddress.city") + @Mapping(target = "completeAddress.country", source = "generalAddress.country") + Person mapPerson(Employee employee); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/GeneralAddress.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/GeneralAddress.java new file mode 100644 index 0000000000..e15ddbb3e1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/GeneralAddress.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +public class GeneralAddress { + + private String city; + private String country; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Issue1828Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Issue1828Test.java new file mode 100644 index 0000000000..a3aa5b3581 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Issue1828Test.java @@ -0,0 +1,98 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1828") +@WithClasses({ + CompleteAddress.class, + Employee.class, + FirstMapper.class, + GeneralAddress.class, + Person.class, + SpecialAddress.class, +}) +public class Issue1828Test { + + @ProcessorTest + public void testMapSpecialAndGeneralAddressSet() { + + Employee employee = new Employee(); + employee.setName( "Mad King" ); + + SpecialAddress specialAddress = new SpecialAddress(); + specialAddress.setLine1( "Building One" ); + specialAddress.setLine2( "Street Two" ); + employee.setSpecialAddress( specialAddress ); + + GeneralAddress generalAddress = new GeneralAddress(); + generalAddress.setCity( "King's Landing" ); + generalAddress.setCountry( "Seven Kingdom" ); + employee.setGeneralAddress( generalAddress ); + + Person person = FirstMapper.INSTANCE.mapPerson( employee ); + assertThat( person.getName() ).isEqualTo( "Mad King" ); + + CompleteAddress completeAddress = person.getCompleteAddress(); + assertThat( completeAddress ).isNotNull(); + assertThat( completeAddress.getLineOne() ).isEqualTo( "Building One" ); + assertThat( completeAddress.getLineTwo() ).isEqualTo( "Street Two" ); + assertThat( completeAddress.getCity() ).isEqualTo( "King's Landing" ); + assertThat( completeAddress.getCountry() ).isEqualTo( "Seven Kingdom" ); + } + + @ProcessorTest + public void testMapGeneralAddressNull() { + + Employee employee = new Employee(); + employee.setName( "Mad King" ); + + SpecialAddress specialAddress = new SpecialAddress(); + specialAddress.setLine1( "Building One" ); + specialAddress.setLine2( "Street Two" ); + employee.setSpecialAddress( specialAddress ); + + Person person = FirstMapper.INSTANCE.mapPerson( employee ); + assertThat( person.getName() ).isEqualTo( "Mad King" ); + + CompleteAddress completeAddress = person.getCompleteAddress(); + assertThat( completeAddress ).isNotNull(); + assertThat( completeAddress.getLineOne() ).isEqualTo( "Building One" ); + assertThat( completeAddress.getLineTwo() ).isEqualTo( "Street Two" ); + assertThat( completeAddress.getCity() ).isNull(); + assertThat( completeAddress.getCountry() ).isNull(); + } + + @ProcessorTest + public void testMapSpecialAddressNull() { + + Employee employee = new Employee(); + employee.setName( "Mad King" ); + + GeneralAddress generalAddress = new GeneralAddress(); + generalAddress.setCity( "King's Landing" ); + generalAddress.setCountry( "Seven Kingdom" ); + employee.setGeneralAddress( generalAddress ); + + Person person = FirstMapper.INSTANCE.mapPerson( employee ); + assertThat( person.getName() ).isEqualTo( "Mad King" ); + + CompleteAddress completeAddress = person.getCompleteAddress(); + assertThat( completeAddress ).isNotNull(); + assertThat( completeAddress.getLineOne() ).isNull(); + assertThat( completeAddress.getLineTwo() ).isNull(); + assertThat( completeAddress.getCity() ).isEqualTo( "King's Landing" ); + assertThat( completeAddress.getCountry() ).isEqualTo( "Seven Kingdom" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Person.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Person.java new file mode 100644 index 0000000000..d23dc86423 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/Person.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +public class Person { + + String name; + private CompleteAddress completeAddress; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public CompleteAddress getCompleteAddress() { + return completeAddress; + } + + public void setCompleteAddress(CompleteAddress completeAddress) { + this.completeAddress = completeAddress; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/SpecialAddress.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/SpecialAddress.java new file mode 100644 index 0000000000..e7e806865b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1828/SpecialAddress.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1828; + +public class SpecialAddress { + + private String line1; + private String line2; + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1881/Issue1881Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1881/Issue1881Test.java new file mode 100644 index 0000000000..21bab07e52 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1881/Issue1881Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1881; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1881") +@WithClasses({ + VehicleDtoMapper.class, +}) +public class Issue1881Test { + + @ProcessorTest + public void shouldCompileCorrectly() { + VehicleDtoMapper.VehicleDto vehicle = VehicleDtoMapper.INSTANCE.map( new VehicleDtoMapper.Vehicle( + "Test", + 100, + "SUV" + ) ); + + assertThat( vehicle.getName() ).isEqualTo( "Test" ); + assertThat( vehicle.getVehicleProperties() ).isNotNull(); + assertThat( vehicle.getVehicleProperties().getSize() ).isEqualTo( 100 ); + assertThat( vehicle.getVehicleProperties().getType() ).isEqualTo( "SUV" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1881/VehicleDtoMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1881/VehicleDtoMapper.java new file mode 100644 index 0000000000..79ccf8f3a0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1881/VehicleDtoMapper.java @@ -0,0 +1,88 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1881; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface VehicleDtoMapper { + + VehicleDtoMapper INSTANCE = Mappers.getMapper( VehicleDtoMapper.class ); + + @Mapping(target = "name", source = "name") + @Mapping(target = "vehicleProperties.size", source = "size") + @Mapping(target = "vehicleProperties.type", source = "type") + VehicleDto map(Vehicle vehicle); + + class VehicleDto { + private String name; + private VehiclePropertiesDto vehicleProperties; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public VehiclePropertiesDto getVehicleProperties() { + return vehicleProperties; + } + + public void setVehicleProperties(VehiclePropertiesDto vehicleProperties) { + this.vehicleProperties = vehicleProperties; + } + } + + class Vehicle { + private final String name; + private final int size; + private final String type; + + public Vehicle(String name, int size, String type) { + this.name = name; + this.size = size; + this.type = type; + } + + public String getName() { + return name; + } + + public int getSize() { + return size; + } + + public String getType() { + return type; + } + } + + class VehiclePropertiesDto { + private int size; + private String type; + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/AstModifyingAnnotationProcessorSaysNo.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/AstModifyingAnnotationProcessorSaysNo.java new file mode 100644 index 0000000000..74cbc7a20c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/AstModifyingAnnotationProcessorSaysNo.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1904; + +import javax.lang.model.type.TypeMirror; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; + +/** + * @author Filip Hrisafov + */ +public class AstModifyingAnnotationProcessorSaysNo implements AstModifyingAnnotationProcessor { + @Override + public boolean isTypeComplete(TypeMirror type) { + if ( type.toString().contains( "CarManualDto" ) ) { + return false; + } + return true; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/Issue1904Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/Issue1904Mapper.java new file mode 100644 index 0000000000..a4f67cb77b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/Issue1904Mapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1904; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue1904Mapper { + + CarManualDto translateManual(CarManual manual); + + /** + * @author Filip Hrisafov + */ + class CarManual { + + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } + + /** + * @author Filip Hrisafov + */ + class CarManualDto { + + private String content; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/Issue1904Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/Issue1904Test.java new file mode 100644 index 0000000000..b369765433 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1904/Issue1904Test.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1904; + +import org.mapstruct.ap.spi.AstModifyingAnnotationProcessor; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@IssueKey("1904") +@WithClasses({ + Issue1904Mapper.class, +}) +@WithServiceImplementation( + provides = AstModifyingAnnotationProcessor.class, + value = AstModifyingAnnotationProcessorSaysNo.class +) +public class Issue1904Test { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { + @Diagnostic( + type = Issue1904Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 14, + message = "No implementation was created for Issue1904Mapper due to having a problem in the erroneous " + + "element org.mapstruct.ap.test.bugs._1904.Issue1904Mapper.CarManualDto. Hint: this often means that " + + "some other annotation processor was supposed to process the erroneous element. You can also enable " + + "MapStruct verbose mode by setting -Amapstruct.verbose=true as a compilation argument." + ) + }) + public void shouldHaveCompilationErrorIfMapperCouldNotBeCreated() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Config.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Config.java new file mode 100644 index 0000000000..d971bce47f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Config.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1933; + +import org.mapstruct.BeanMapping; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingInheritanceStrategy; + +/** + * @author Sjaak Derksen + */ +@MapperConfig(mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_FROM_CONFIG) +public interface Issue1933Config { + + @BeanMapping(ignoreByDefault = true) + Entity updateEntity(Dto dto); + + class Entity { + //CHECKSTYLE:OFF + public String id; + public int updateCount; + //CHECKSTYLE:ON + } + + class Dto { + //CHECKSTYLE:OFF + public String id; + public int updateCount; + //CHECKSTYLE:ON + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Mapper.java new file mode 100644 index 0000000000..fdaa28c1ee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1933; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper(config = Issue1933Config.class) +public interface Issue1933Mapper { + + Issue1933Mapper INSTANCE = Mappers.getMapper( Issue1933Mapper.class ); + + @Mapping(target = "updateCount", source = "updateCount") + Issue1933Config.Entity map(Issue1933Config.Dto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Test.java new file mode 100644 index 0000000000..5d1ca351f9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1933/Issue1933Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1933; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@IssueKey("1933") +@WithClasses({ + Issue1933Config.class, + Issue1933Mapper.class +}) +public class Issue1933Test { + + @ProcessorTest + public void shouldIgnoreIdAndMapUpdateCount() { + + Issue1933Config.Dto dto = new Issue1933Config.Dto(); + dto.id = "id"; + dto.updateCount = 5; + + Issue1933Config.Entity entity = Issue1933Mapper.INSTANCE.map( dto ); + + assertThat( entity.id ).isNull(); + assertThat( entity.updateCount ).isEqualTo( 5 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1966/Issue1966Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1966/Issue1966Mapper.java new file mode 100644 index 0000000000..13f4d489b9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1966/Issue1966Mapper.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1966; + +import java.util.Collections; +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( imports = Collections.class ) +public interface Issue1966Mapper { + + Issue1966Mapper INSTANCE = Mappers.getMapper( Issue1966Mapper.class ); + + @Mapping(target = "previousNames", + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + defaultExpression = "java(Collections.emptyList())") + Animal toAnimal(AnimalRecord record); + + class AnimalRecord { + + private String[] previousNames; + + public String[] getPreviousNames() { + return previousNames; + } + + public void setPreviousNames(String[] previousNames) { + this.previousNames = previousNames; + } + } + + class Animal { + + private List previousNames; + + public List getPreviousNames() { + return previousNames; + } + + public void setPreviousNames(List previousNames) { + this.previousNames = previousNames; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1966/Issue1966Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1966/Issue1966Test.java new file mode 100644 index 0000000000..528f45594a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1966/Issue1966Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1966; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@IssueKey("1966") +@WithClasses({ + Issue1966Mapper.class +}) +public class Issue1966Test { + + @ProcessorTest + public void shouldSelectDefaultExpressionEvenWhenSourceInMappingIsNotSpecified() { + + Issue1966Mapper.AnimalRecord dto = new Issue1966Mapper.AnimalRecord(); + + Issue1966Mapper.Animal entity = Issue1966Mapper.INSTANCE.toAnimal( dto ); + + assertThat( entity.getPreviousNames() ).isNotNull(); + assertThat( entity.getPreviousNames() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/Car.java new file mode 100644 index 0000000000..87722cdb50 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/Car.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1997; + +/** + * @author Filip Hrisafov + */ +public class Car { + private String model; + + private Car(Builder builder) { + this.model = builder.model; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String model; + + public Builder model(String model) { + this.model = model; + return this; + } + + public Car build() { + return new Car( this ); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarDetail.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarDetail.java new file mode 100644 index 0000000000..84472d1263 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarDetail.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1997; + +/** + * @author Filip Hrisafov + */ +public class CarDetail { + private String model; + + private CarDetail(Builder builder) { + this.model = builder.model; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String model; + + public Builder model(String model) { + this.model = model; + return this; + } + + public CarDetail build() { + return new CarDetail( this ); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarInsurance.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarInsurance.java new file mode 100644 index 0000000000..83fb4350dc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarInsurance.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1997; + +/** + * @author Filip Hrisafov + */ +public class CarInsurance { + private CarDetail detail; + + private CarInsurance(Builder builder) { + this.detail = builder.detail; + } + + public CarDetail getDetail() { + return detail; + } + + public void setDetail(CarDetail detail) { + this.detail = detail; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private CarDetail detail; + + public Builder detail(CarDetail detail) { + this.detail = detail; + return this; + } + + public CarInsurance build() { + return new CarInsurance( this ); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarInsuranceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarInsuranceMapper.java new file mode 100644 index 0000000000..79369b9a79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/CarInsuranceMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1997; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CarInsuranceMapper { + + CarInsuranceMapper INSTANCE = Mappers.getMapper( CarInsuranceMapper.class ); + + @Mapping(source = "model", target = "detail.model") + void update(Car source, @MappingTarget CarInsurance target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/Issue1997Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/Issue1997Test.java new file mode 100644 index 0000000000..5645ca173b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_1997/Issue1997Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._1997; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Car.class, + CarDetail.class, + CarInsurance.class, + CarInsuranceMapper.class +}) +class Issue1997Test { + + @ProcessorTest + void shouldCorrectCreateIntermediateObjectsWithBuilder() { + Car source = Car.builder().model( "Model S" ).build(); + CarInsurance target = CarInsurance.builder().build(); + assertThat( target.getDetail() ).isNull(); + + CarInsuranceMapper.INSTANCE.update( source, target ); + + assertThat( target.getDetail() ).isNotNull(); + assertThat( target.getDetail().getModel() ).isEqualTo( "Model S" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Entity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Entity.java new file mode 100644 index 0000000000..38ec42ee7d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Entity.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2001; + +import java.util.Set; + +/** + * @author Filip Hrisafov + */ +public +class Entity { + + private Set extras; + + public Set getExtras() { + return extras; + } + + public void setExtras(Set extras) { + this.extras = extras; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/EntityExtra.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/EntityExtra.java new file mode 100644 index 0000000000..ecd0dbb1f5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/EntityExtra.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2001; + +/** + * @author Filip Hrisafov + */ +public +class EntityExtra { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Form.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Form.java new file mode 100644 index 0000000000..a3656acecf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Form.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2001; + +/** + * @author Filip Hrisafov + */ +public +class Form { + + private FormExtra[] extras; + + public FormExtra[] getExtras() { + return extras; + } + + public void setExtras(FormExtra[] extras) { + this.extras = extras; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/FormExtra.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/FormExtra.java new file mode 100644 index 0000000000..2ff150f4ff --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/FormExtra.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2001; + +/** + * @author Filip Hrisafov + */ +public +class FormExtra { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Issue2001Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Issue2001Mapper.java new file mode 100644 index 0000000000..272d23bb5d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Issue2001Mapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2001; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2001Mapper { + + Form map(Entity entity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Issue2001Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Issue2001Test.java new file mode 100644 index 0000000000..52525e9e9f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2001/Issue2001Test.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2001; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2001") +@WithClasses( { + Entity.class, + EntityExtra.class, + Form.class, + FormExtra.class, + Issue2001Mapper.class +} ) +public class Issue2001Test { + + @ProcessorTest + public void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Issue2018Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Issue2018Mapper.java new file mode 100644 index 0000000000..b75450ce25 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Issue2018Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2018; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2018Mapper { + + Issue2018Mapper INSTANCE = Mappers.getMapper( Issue2018Mapper.class ); + + @Mapping(target = "some_value", source = "someValue") + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Issue2018Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Issue2018Test.java new file mode 100644 index 0000000000..68719b9ff0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Issue2018Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2018; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2018") +@WithClasses({ + Issue2018Mapper.class, + Source.class, + Target.class +}) +public class Issue2018Test { + + @ProcessorTest + public void shouldGenerateCorrectCode() { + Source source = new Source(); + source.setSomeValue( "value" ); + + Target target = Issue2018Mapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getSome_value() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Source.java new file mode 100644 index 0000000000..767952da1a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2018; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private String someValue; + + public String getSomeValue() { + return someValue; + } + + public void setSomeValue(String someValue) { + this.someValue = someValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Target.java new file mode 100644 index 0000000000..1d8c1ae3b2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2018/Target.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2018; + +/** + * @author Filip Hrisafov + */ +public class Target { + + // CHECKSTYLE:OFF + private String some_value; + + public String getSome_value() { + return some_value; + } + + public void setSome_value(String some_value) { + this.some_value = some_value; + } + // CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2021/Issue2021Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2021/Issue2021Mapper.java new file mode 100644 index 0000000000..4627f22323 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2021/Issue2021Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2021; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +@DecoratedWith(Issue2021Mapper.Decorator.class) +public interface Issue2021Mapper { + + abstract class Decorator implements Issue2021Mapper { + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2021/Issue2021Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2021/Issue2021Test.java new file mode 100644 index 0000000000..bb6ef326b6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2021/Issue2021Test.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2021; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2021") +@WithClasses({ + Issue2021Mapper.class +}) +public class Issue2021Test { + + @ProcessorTest + public void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/Issue2023Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/Issue2023Mapper.java new file mode 100644 index 0000000000..a2fafb7a2d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/Issue2023Mapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2023; + +import java.util.UUID; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2023Mapper { + + Issue2023Mapper INSTANCE = Mappers.getMapper( Issue2023Mapper.class ); + + @Mapping(target = "correlationId", source = "correlationId", defaultExpression = "java(UUID.randomUUID())") + NewPersonRequest createRequest(PersonDto person, UUID correlationId); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/Issue2023Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/Issue2023Test.java new file mode 100644 index 0000000000..99c97d9eb5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/Issue2023Test.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2023; + +import java.util.UUID; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2023") +@WithClasses({ + Issue2023Mapper.class, + NewPersonRequest.class, + PersonDto.class, +}) +public class Issue2023Test { + + @ProcessorTest + public void shouldUseDefaultExpressionCorrectly() { + PersonDto person = new PersonDto(); + person.setName( "John" ); + person.setEmail( "john@doe.com" ); + + NewPersonRequest request = Issue2023Mapper.INSTANCE.createRequest( person, null ); + + assertThat( request ).isNotNull(); + assertThat( request.getName() ).isEqualTo( "John" ); + assertThat( request.getEmail() ).isEqualTo( "john@doe.com" ); + assertThat( request.getCorrelationId() ).isNotNull(); + + UUID correlationId = UUID.randomUUID(); + request = Issue2023Mapper.INSTANCE.createRequest( person, correlationId ); + + assertThat( request ).isNotNull(); + assertThat( request.getName() ).isEqualTo( "John" ); + assertThat( request.getEmail() ).isEqualTo( "john@doe.com" ); + assertThat( request.getCorrelationId() ).isEqualTo( correlationId ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/NewPersonRequest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/NewPersonRequest.java new file mode 100644 index 0000000000..98f3d0b5b6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/NewPersonRequest.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2023; + +import java.util.UUID; + +/** + * @author Filip Hrisafov + */ +public class NewPersonRequest { + + private String name; + private String email; + private UUID correlationId; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public UUID getCorrelationId() { + return correlationId; + } + + public void setCorrelationId(UUID correlationId) { + this.correlationId = correlationId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/PersonDto.java new file mode 100644 index 0000000000..d2551c50c6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2023/PersonDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2023; + +/** + * @author Filip Hrisafov + */ +public class PersonDto { + + private String name; + private String email; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2042/Issue2402Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2042/Issue2402Mapper.java new file mode 100644 index 0000000000..3fe52aaafd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2042/Issue2402Mapper.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2042; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2402Mapper { + + Issue2402Mapper INSTANCE = Mappers.getMapper( Issue2402Mapper.class ); + + @Mapping(target = ".", source = "source.info") + Target map(Source source, String other); + + class Target { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + class Source { + + private final Info info; + + public Source(Info info) { + this.info = info; + } + + public Info getInfo() { + return info; + } + } + + class Info { + private final String name; + + public Info(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2042/Issue2402Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2042/Issue2402Test.java new file mode 100644 index 0000000000..9d1d18dac6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2042/Issue2402Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2042; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2402") +@WithClasses({ + Issue2402Mapper.class +}) +public class Issue2402Test { + + @ProcessorTest + public void shouldCompile() { + Issue2402Mapper.Target target = Issue2402Mapper.INSTANCE. + map( + new Issue2402Mapper.Source( new Issue2402Mapper.Info( "test" ) ), + "other test" + ); + + assertThat( target.getName() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java new file mode 100644 index 0000000000..9d38e8bf45 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077ErroneousMapper.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2077; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +/** + * @author Sjaak Derksen + */ +@Mapper( unmappedTargetPolicy = ReportingPolicy.ERROR ) +public interface Issue2077ErroneousMapper { + + @Mapping(target = "s1", defaultValue = "xyz" ) + Target map(String source); + + class Target { + + private String s1; + + public String getS1() { + return s1; + } + + public void setS1(String s1) { + this.s1 = s1; + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java new file mode 100644 index 0000000000..607c1137f8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2077/Issue2077Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2077; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static javax.tools.Diagnostic.Kind.ERROR; + +/** + * @author Sjaak Derksen + */ +@IssueKey("2077") +public class Issue2077Test { + + @ProcessorTest + @WithClasses(Issue2077ErroneousMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = Issue2077ErroneousMapper.class, + kind = ERROR, + line = 18, + message = "The type of parameter \"source\" has no property named \"s1\". Please define the source " + + "property explicitly.") + } + ) + public void shouldNotCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101AdditionalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101AdditionalMapper.java new file mode 100644 index 0000000000..ea745d6bc1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101AdditionalMapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2101; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2101AdditionalMapper { + + Issue2101AdditionalMapper INSTANCE = Mappers.getMapper( Issue2101AdditionalMapper.class ); + + @Mapping(target = "value1", source = "value.nestedValue1") + @Mapping(target = "value2", source = "value.nestedValue2") + @Mapping(target = "value3", source = "valueThrowOffPath") + Target map1(Source source); + + @InheritConfiguration + @Mapping(target = "value2", source = "value.nestedValue1") + @Mapping(target = "value3", constant = "test") + Target map2(Source source); + + //CHECKSTYLE:OFF + class Source { + public String valueThrowOffPath; + public NestedSource value; + } + + class Target { + public String value1; + public String value2; + public String value3; + } + + class NestedSource { + public String nestedValue1; + public String nestedValue2; + } + //CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101Mapper.java new file mode 100644 index 0000000000..5a1f01fa72 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101Mapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2101; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2101Mapper { + + Issue2101Mapper INSTANCE = Mappers.getMapper( Issue2101Mapper.class ); + + @Mapping(target = "value1", source = "codeValue1") + @Mapping(target = "value2", source = "codeValue2") + Source map(Target target); + + @InheritInverseConfiguration + @Mapping(target = "codeValue1.code", constant = "c1") + @Mapping(target = "codeValue1.value", source = "value1") + @Mapping(target = "codeValue2.code", constant = "c2") + @Mapping(target = "codeValue2.value", source = "value2") + Target map(Source source); + + default String mapFrom( CodeValuePair cv ) { + return cv.code; + } + + //CHECKSTYLE:OFF + class Source { + public String value1; + public String value2; + } + + class Target { + public CodeValuePair codeValue1; + public CodeValuePair codeValue2; + } + + class CodeValuePair { + public String code; + public String value; + } + //CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101Test.java new file mode 100644 index 0000000000..96c3f31b12 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2101Test.java @@ -0,0 +1,80 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2101; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2101") +public class Issue2101Test { + + @ProcessorTest + @WithClasses(Issue2101Mapper.class) + public void shouldMap() { + + Issue2101Mapper.Source source = new Issue2101Mapper.Source(); + source.value1 = "v1"; + source.value2 = "v2"; + + Issue2101Mapper.Target target = Issue2101Mapper.INSTANCE.map( source ); + + assertThat( target.codeValue1.code ).isEqualTo( "c1" ); + assertThat( target.codeValue1.value ).isEqualTo( "v1" ); + assertThat( target.codeValue2.code ).isEqualTo( "c2" ); + assertThat( target.codeValue2.value ).isEqualTo( "v2" ); + + } + + @ProcessorTest + @WithClasses(Issue2101AdditionalMapper.class) + public void shouldMapSomeAdditionalTests1() { + Issue2101AdditionalMapper.Source source = new Issue2101AdditionalMapper.Source(); + source.value = new Issue2101AdditionalMapper.NestedSource(); + source.value.nestedValue1 = "value1"; + source.value.nestedValue2 = "value2"; + source.valueThrowOffPath = "value3"; + + Issue2101AdditionalMapper.Target target = Issue2101AdditionalMapper.INSTANCE.map1( source ); + assertThat( target.value1 ).isEqualTo( "value1" ); + assertThat( target.value2 ).isEqualTo( "value2" ); + assertThat( target.value3 ).isEqualTo( "value3" ); + } + + @ProcessorTest + @WithClasses(Issue2101AdditionalMapper.class) + public void shouldMapSomeAdditionalTests2() { + Issue2101AdditionalMapper.Source source = new Issue2101AdditionalMapper.Source(); + source.value = new Issue2101AdditionalMapper.NestedSource(); + source.value.nestedValue1 = "value1"; + source.value.nestedValue2 = "value2"; + source.valueThrowOffPath = "value3"; + + Issue2101AdditionalMapper.Target target = Issue2101AdditionalMapper.INSTANCE.map2( source ); + assertThat( target.value1 ).isEqualTo( "value1" ); + assertThat( target.value2 ).isEqualTo( "value1" ); + assertThat( target.value3 ).isEqualTo( "test" ); + + } + + @ProcessorTest + @WithClasses(Issue2102IgnoreAllButMapper.class) + public void shouldApplyIgnoreAllButTemplateOfMethod1() { + + Issue2102IgnoreAllButMapper.Source source = new Issue2102IgnoreAllButMapper.Source(); + source.value1 = "value1"; + source.value2 = "value2"; + + Issue2102IgnoreAllButMapper.Target target = Issue2102IgnoreAllButMapper.INSTANCE.map1( source ); + assertThat( target.value1 ).isEqualTo( "value1" ); + + target = Issue2102IgnoreAllButMapper.INSTANCE.map2( source ); + assertThat( target.value1 ).isEqualTo( "value2" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2102IgnoreAllButMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2102IgnoreAllButMapper.java new file mode 100644 index 0000000000..9634ed310b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2101/Issue2102IgnoreAllButMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2101; + +import org.mapstruct.BeanMapping; +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2102IgnoreAllButMapper { + + Issue2102IgnoreAllButMapper INSTANCE = Mappers.getMapper( Issue2102IgnoreAllButMapper.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping(target = "value1") // but do map value1 + Target map1(Source source); + + @InheritConfiguration + @Mapping(target = "value1", source = "value2" ) + Target map2(Source source); + + //CHECKSTYLE:OFF + class Source { + public String value1; + public String value2; + } + + class Target { + public String value1; + } + //CHECKSTYLE:ON + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Issue2109Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Issue2109Mapper.java new file mode 100644 index 0000000000..7542c2c0cf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Issue2109Mapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2109; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2109Mapper { + + Issue2109Mapper INSTANCE = Mappers.getMapper( Issue2109Mapper.class ); + + Target map(Source source); + + @Mapping(target = "data", defaultExpression = "java(new byte[0])") + Target mapWithEmptyData(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Issue2109Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Issue2109Test.java new file mode 100644 index 0000000000..bc1deed110 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Issue2109Test.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2109; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2109") +@WithClasses({ + Issue2109Mapper.class, + Source.class, + Target.class, +}) +public class Issue2109Test { + + @ProcessorTest + public void shouldCorrectlyMapArrayInConstructorMapping() { + Target target = Issue2109Mapper.INSTANCE.map( new Source( 100L, new byte[] { 100, 120, 40, 40 } ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( 100L ); + assertThat( target.getData() ).containsExactly( 100, 120, 40, 40 ); + + target = Issue2109Mapper.INSTANCE.map( new Source( 50L, null ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( 50L ); + assertThat( target.getData() ).isNull(); + + target = Issue2109Mapper.INSTANCE.mapWithEmptyData( new Source( 100L, new byte[] { 100, 120, 40, 40 } ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( 100L ); + assertThat( target.getData() ).containsExactly( 100, 120, 40, 40 ); + + target = Issue2109Mapper.INSTANCE.mapWithEmptyData( new Source( 50L, null ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( 50L ); + assertThat( target.getData() ).isEmpty(); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Source.java new file mode 100644 index 0000000000..a0aba8ce8b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Source.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2109; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final Long id; + private final byte[] data; + + public Source(Long id, byte[] data) { + this.id = id; + this.data = data; + } + + public Long getId() { + return id; + } + + public byte[] getData() { + return data; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Target.java new file mode 100644 index 0000000000..2e44bc21b6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2109/Target.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2109; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final Long id; + private final byte[] data; + + public Target(Long id, byte[] data) { + this.id = id; + this.data = data; + } + + public Long getId() { + return id; + } + + public byte[] getData() { + return data; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2111/Issue2111Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2111/Issue2111Mapper.java new file mode 100644 index 0000000000..9bf63385fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2111/Issue2111Mapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2111; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +import static java.util.Collections.singletonList; + +@Mapper +public interface Issue2111Mapper { + + @Mapping(target = "strs", source = "ex", qualifiedByName = "wrap") + DTO map(UseExample from); + + @Named("wrap") + default String mapExample(Example ex) { + return ex.name; + } + + @Named("wrap") + default List wrapInList(T t) { + return singletonList( t ); + } + + //CHECKSTYLE:OFF + class Example { + public String name; + } + + class UseExample { + public Example ex; + } + + class DTO { + public List strs; + } + //CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2111/Issue2111Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2111/Issue2111Test.java new file mode 100644 index 0000000000..a3006ceb9c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2111/Issue2111Test.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2111; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Sjaak Derksen + */ +@IssueKey("2111") +@WithClasses( Issue2111Mapper.class ) +public class Issue2111Test { + + @ProcessorTest + public void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2117/Issue2117Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2117/Issue2117Mapper.java new file mode 100644 index 0000000000..06dd72fafd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2117/Issue2117Mapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2117; + +import java.nio.file.AccessMode; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2117Mapper { + + Issue2117Mapper INSTANCE = Mappers.getMapper( Issue2117Mapper.class ); + + @Mapping(target = "accessMode", source = "accessMode") + Target toTarget(AccessMode accessMode, String otherSource); + + class Target { + // CHECKSTYLE:OFF + public AccessMode accessMode; + // CHECKSTYLE ON + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2117/Issue2117Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2117/Issue2117Test.java new file mode 100644 index 0000000000..984aa2daa9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2117/Issue2117Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2117; + +import java.nio.file.AccessMode; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2117") +@WithClasses({ + Issue2117Mapper.class +}) +public class Issue2117Test { + + @ProcessorTest + public void shouldCompile() { + + Issue2117Mapper.Target target = Issue2117Mapper.INSTANCE.toTarget( AccessMode.READ, null ); + + assertThat( target ).isNotNull(); + assertThat( target.accessMode ).isEqualTo( AccessMode.READ ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2121/Issue2121Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2121/Issue2121Mapper.java new file mode 100644 index 0000000000..f61300c0ee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2121/Issue2121Mapper.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2121; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2121Mapper { + + Issue2121Mapper INSTANCE = Mappers.getMapper( Issue2121Mapper.class ); + + Target map(Source source); + + class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + + private final SourceEnum value; + + public Source(SourceEnum value) { + this.value = value; + } + + public SourceEnum getValue() { + return value; + } + } + + enum SourceEnum { + VALUE1, + VALUE2 + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2121/Issue2121Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2121/Issue2121Test.java new file mode 100644 index 0000000000..24bb88450b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2121/Issue2121Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2121; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2121") +@WithClasses(Issue2121Mapper.class) +public class Issue2121Test { + + @ProcessorTest + public void shouldCompile() { + Issue2121Mapper mapper = Issue2121Mapper.INSTANCE; + + Issue2121Mapper.Target target = mapper.map( new Issue2121Mapper.Source( Issue2121Mapper.SourceEnum.VALUE1 ) ); + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "VALUE1" ); + + target = mapper.map( new Issue2121Mapper.Source( null ) ); + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Method2MethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Method2MethodMapper.java new file mode 100644 index 0000000000..033a314af2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Method2MethodMapper.java @@ -0,0 +1,103 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2122; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Bandowski + */ +@Mapper +public interface Issue2122Method2MethodMapper { + + Issue2122Method2MethodMapper INSTANCE = Mappers.getMapper( Issue2122Method2MethodMapper.class ); + + @Mapping(target = "embeddedTarget", source = "value") + @Mapping(target = "embeddedMapTarget", source = "value") + @Mapping(target = "embeddedListListTarget", source = "value") + Target toTarget(Source source); + + EmbeddedTarget toEmbeddedTarget(String value); + + default List singleEntry(T entry) { + return Collections.singletonList( entry ); + } + + default List> singleNestedListEntry(T entry) { + return Collections.singletonList( Collections.singletonList( entry ) ); + } + + default HashMap singleEntryMap(T entry) { + HashMap result = new HashMap<>( ); + result.put( "test", entry ); + return result; + } + + class Source { + String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Target { + List embeddedTarget; + + Map embeddedMapTarget; + + List> embeddedListListTarget; + + public List getEmbeddedTarget() { + return embeddedTarget; + } + + public void setEmbeddedTarget(List embeddedTarget) { + this.embeddedTarget = embeddedTarget; + } + + public Map getEmbeddedMapTarget() { + return embeddedMapTarget; + } + + public void setEmbeddedMapTarget( Map embeddedMapTarget) { + this.embeddedMapTarget = embeddedMapTarget; + } + + public List> getEmbeddedListListTarget() { + return embeddedListListTarget; + } + + public void setEmbeddedListListTarget( + List> embeddedListListTarget) { + this.embeddedListListTarget = embeddedListListTarget; + } + } + + class EmbeddedTarget { + String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Method2TypeConversionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Method2TypeConversionMapper.java new file mode 100644 index 0000000000..43d40aa772 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Method2TypeConversionMapper.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2122; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public interface Issue2122Method2TypeConversionMapper { + + Issue2122Method2TypeConversionMapper INSTANCE = Mappers.getMapper( Issue2122Method2TypeConversionMapper.class ); + + @Mapping(target = "value", source = "strings") + Target toTarget(Source source); + + default T toFirstElement(List entry) { + return entry.get( 0 ); + } + + class Source { + List strings; + + public List getStrings() { + return strings; + } + + public void setStrings(List strings) { + this.strings = strings; + } + } + + class Target { + Integer value; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Test.java new file mode 100644 index 0000000000..f0a82d8f0a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122Test.java @@ -0,0 +1,76 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2122; + +import java.util.Collections; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Christian Bandowski + */ +@IssueKey("2122") +public class Issue2122Test { + + @ProcessorTest + @WithClasses( Issue2122Method2MethodMapper.class ) + public void shouldMapMethod2Method() { + Issue2122Method2MethodMapper.Source source = new Issue2122Method2MethodMapper.Source(); + source.setValue( "value" ); + + Issue2122Method2MethodMapper.Target target = Issue2122Method2MethodMapper.INSTANCE.toTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getEmbeddedTarget() ).isNotNull(); + assertThat( target.getEmbeddedTarget() ).hasSize( 1 ) + .element( 0 ) + .extracting( Issue2122Method2MethodMapper.EmbeddedTarget::getValue ).isEqualTo( "value" ); + assertThat( target.getEmbeddedMapTarget() ).isNotNull(); + assertThat( target.getEmbeddedMapTarget() ).hasSize( 1 ); + assertThat( target.getEmbeddedMapTarget().get( "test" ) ) + .extracting( Issue2122Method2MethodMapper.EmbeddedTarget::getValue ).isEqualTo( "value" ); + assertThat( target.getEmbeddedListListTarget() ).isNotNull(); + assertThat( target.getEmbeddedListListTarget() ).hasSize( 1 ); + assertThat( target.getEmbeddedListListTarget().get( 0 ) ).hasSize( 1 ) + .element( 0 ) + .extracting( Issue2122Method2MethodMapper.EmbeddedTarget::getValue ).isEqualTo( "value" ); + } + + @ProcessorTest + @WithClasses( Issue2122TypeConversion2MethodMapper.class ) + public void shouldMapTypeConversion2Method() { + Issue2122TypeConversion2MethodMapper.Source source = new Issue2122TypeConversion2MethodMapper.Source(); + source.setValue( 5 ); + + Issue2122TypeConversion2MethodMapper.Target target = + Issue2122TypeConversion2MethodMapper.INSTANCE.toTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getStrings() ).isNotNull(); + assertThat( target.getStrings() ).hasSize( 1 ) + .element( 0 ) + .isEqualTo( "5" ); + } + + @ProcessorTest + @WithClasses( Issue2122Method2TypeConversionMapper.class ) + public void shouldMapMethod2TypeConversion() { + Issue2122Method2TypeConversionMapper.Source source = new Issue2122Method2TypeConversionMapper.Source(); + source.setStrings( Collections.singletonList( "5" ) ); + + Issue2122Method2TypeConversionMapper.Target target = + Issue2122Method2TypeConversionMapper.INSTANCE.toTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( 5 ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122TypeConversion2MethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122TypeConversion2MethodMapper.java new file mode 100644 index 0000000000..2555f53dee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2122/Issue2122TypeConversion2MethodMapper.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2122; + +import java.util.Collections; +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public interface Issue2122TypeConversion2MethodMapper { + + Issue2122TypeConversion2MethodMapper INSTANCE = Mappers.getMapper( Issue2122TypeConversion2MethodMapper.class ); + + @Mapping(target = "strings", source = "value") + Target toTarget(Source source); + + default List singleEntry(T entry) { + return Collections.singletonList( entry ); + } + + class Source { + Integer value; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + } + + class Target { + List strings; + + public List getStrings() { + return strings; + } + + public void setStrings(List strings) { + this.strings = strings; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/CommitComment.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/CommitComment.java new file mode 100644 index 0000000000..9067f82c3d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/CommitComment.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2124; + +/** + * @author Filip Hrisafov + */ +public class CommitComment { + + private final Integer issueId; + + public CommitComment(Integer issueId) { + this.issueId = issueId; + } + + public Integer getIssueId() { + return issueId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/Issue2124Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/Issue2124Mapper.java new file mode 100644 index 0000000000..af6250c7f5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/Issue2124Mapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2124; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2124Mapper { + + Issue2124Mapper INSTANCE = Mappers.getMapper( Issue2124Mapper.class ); + + @Mapping(target = "issueId", source = "comment.issueId", qualifiedByName = "mapped") + CommitComment clone(CommitComment comment, String otherSource); + + @Named("mapped") + default Integer mapIssueNumber(int issueNumber) { + return issueNumber * 2; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/Issue2124Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/Issue2124Test.java new file mode 100644 index 0000000000..f2f9873fdb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2124/Issue2124Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2124; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2124") +@WithClasses({ + CommitComment.class, + Issue2124Mapper.class +}) +public class Issue2124Test { + + @ProcessorTest + public void shouldCompile() { + + CommitComment clone = Issue2124Mapper.INSTANCE.clone( new CommitComment( 100 ), null ); + assertThat( clone ).isNotNull(); + assertThat( clone.getIssueId() ).isEqualTo( 200 ); + + clone = Issue2124Mapper.INSTANCE.clone( new CommitComment( null ), null ); + assertThat( clone ).isNotNull(); + assertThat( clone.getIssueId() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Comment.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Comment.java new file mode 100644 index 0000000000..13fe680bb0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Comment.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2125; + +/** + * @author Filip Hrisafov + */ +public class Comment { + private final Integer issueId; + private final String comment; + + public Comment(Integer issueId, String comment) { + this.issueId = issueId; + this.comment = comment; + } + + public Integer getIssueId() { + return issueId; + } + + public String getComment() { + return comment; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125ErroneousMapper.java new file mode 100644 index 0000000000..bdca172003 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125ErroneousMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2125; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +@Mapper +public interface Issue2125ErroneousMapper { + + @Mapping(target = "issueId", qualifiedByName = "mapIssueNumber") + @Mapping( target = "comment", ignore = true) + Comment clone(Repository repository); + + @Mapping(target = "issueId", qualifiedByName = "mapIssueNumber") + @Mapping( target = "comment", ignore = true) + Comment clone(Comment comment, Repository repository); + + @Named("mapIssueNumber") + default Integer mapIssueNumber(Integer issueNumber) { + return issueNumber != null ? issueNumber + 1 : null; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125Mapper.java new file mode 100644 index 0000000000..83cf0e1b28 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125Mapper.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2125; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2125Mapper { + + Issue2125Mapper INSTANCE = Mappers.getMapper( Issue2125Mapper.class ); + + // In this case the issueId from the Comment is used + Comment clone(Comment comment, Integer issueId); + + // When source is not defined then we will use the issueId from the Comment, + // same as when there was no mapping + @Mapping(target = "issueId", qualifiedByName = "mapIssueNumber") + Comment cloneWithQualifier(Comment comment, Integer issueId); + + // When source is defined then we will source the parameter name + @Mapping(target = "issueId", source = "issueId", qualifiedByName = "mapIssueNumber") + Comment cloneWithQualifierExplicitSource(Comment comment, Integer issueId); + + @Named("mapIssueNumber") + default Integer mapIssueNumber(Integer issueNumber) { + return issueNumber != null ? issueNumber + 1 : null; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125Test.java new file mode 100644 index 0000000000..69a564edf0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Issue2125Test.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2125; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2125") +@WithClasses({ + Comment.class, + Repository.class, +}) +public class Issue2125Test { + + @ProcessorTest + @WithClasses({ + Issue2125Mapper.class + }) + public void shouldSelectProperMethod() { + + Comment comment = Issue2125Mapper.INSTANCE.clone( + new Comment( 2125, "Fix issue" ), + 1000 + ); + + assertThat( comment ).isNotNull(); + assertThat( comment.getIssueId() ).isEqualTo( 2125 ); + + comment = Issue2125Mapper.INSTANCE.cloneWithQualifier( + new Comment( 2125, "Fix issue" ), + 1000 + ); + + assertThat( comment ).isNotNull(); + assertThat( comment.getIssueId() ).isEqualTo( 2126 ); + + comment = Issue2125Mapper.INSTANCE.cloneWithQualifierExplicitSource( + new Comment( 2125, "Fix issue" ), + 1000 + ); + + assertThat( comment ).isNotNull(); + assertThat( comment.getIssueId() ).isEqualTo( 1001 ); + } + + @ProcessorTest + @WithClasses({ + Issue2125ErroneousMapper.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = Issue2125ErroneousMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 15, + alternativeLine = 17, // For some reason javac reports the error on the method instead of the annotation + message = "The type of parameter \"repository\" has no property named \"issueId\". Please define the " + + "source property explicitly."), + }) + public void shouldReportErrorWhenMultipleSourcesMatch() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Repository.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Repository.java new file mode 100644 index 0000000000..bf0c80984f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2125/Repository.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2125; + +/** + * @author Filip Hrisafov + */ +public class Repository { + + private final String owner; + private final String name; + + public Repository(String owner, String name) { + this.owner = owner; + this.name = name; + } + + public String getOwner() { + return owner; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2131/Issue2131Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2131/Issue2131Mapper.java new file mode 100644 index 0000000000..a0e0b1df7f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2131/Issue2131Mapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2131; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface Issue2131Mapper { + + Issue2131Mapper INSTANCE = Mappers.getMapper( Issue2131Mapper.class ); + + TestDto map(TestModel source); + + class TestModel { + private final String name; + + public TestModel(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class TestDto { + private String name; + + public TestDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2131/Issue2131Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2131/Issue2131Test.java new file mode 100644 index 0000000000..6f7a3ec8a3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2131/Issue2131Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2131; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2131") +@WithClasses(Issue2131Mapper.class) +public class Issue2131Test { + + @ProcessorTest + public void shouldCompile() { + Issue2131Mapper mapper = Issue2131Mapper.INSTANCE; + + Issue2131Mapper.TestDto target = mapper.map( new Issue2131Mapper.TestModel( "test" ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "test" ); + + target = mapper.map( new Issue2131Mapper.TestModel( null ) ); + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2133/Issue2133Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2133/Issue2133Mapper.java new file mode 100644 index 0000000000..484620c0c4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2133/Issue2133Mapper.java @@ -0,0 +1,75 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2133; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2133Mapper { + + Issue2133Mapper INSTANCE = Mappers.getMapper( Issue2133Mapper.class ); + + @BeanMapping(resultType = Target.class) + AbstractTarget map(Source source); + + class Source { + + private EmbeddedDto embedded; + + public EmbeddedDto getEmbedded() { + return embedded; + } + + public void setEmbedded(EmbeddedDto embedded) { + this.embedded = embedded; + } + } + + class Target extends AbstractTarget { + } + + abstract class AbstractTarget { + + private EmbeddedEntity embedded; + + public EmbeddedEntity getEmbedded() { + return embedded; + } + + public void setEmbedded(EmbeddedEntity embedded) { + this.embedded = embedded; + } + } + + class EmbeddedDto { + + private String s1; + + public String getS1() { + return s1; + } + + public void setS1(String s1) { + this.s1 = s1; + } + } + + class EmbeddedEntity { + + private String s1; + + public String getS1() { + return s1; + } + + public void setS1(String s1) { + this.s1 = s1; + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2133/Issue2133Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2133/Issue2133Test.java new file mode 100644 index 0000000000..5f78b3fdde --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2133/Issue2133Test.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2133; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@IssueKey("2133") +@WithClasses( Issue2133Mapper.class ) +public class Issue2133Test { + + @ProcessorTest + public void shouldCompile() { + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2142/Issue2142Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2142/Issue2142Mapper.java new file mode 100644 index 0000000000..198976b37e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2142/Issue2142Mapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2142; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2142Mapper { + + Issue2142Mapper INSTANCE = Mappers.getMapper( Issue2142Mapper.class ); + + _Target map(Source source); + + // CHECKSTYLE:OFF + class _Target { + // CHECKSTYLE:ON + private final String value; + + public _Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2142/Issue2142Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2142/Issue2142Test.java new file mode 100644 index 0000000000..287c39c175 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2142/Issue2142Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2142; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2142") +@WithClasses(Issue2142Mapper.class) +public class Issue2142Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( Issue2142Mapper.class ); + + @ProcessorTest + public void underscorePrefixShouldBeStrippedFromGeneratedLocalVariables() { + Issue2142Mapper._Target target = Issue2142Mapper.INSTANCE.map( new Issue2142Mapper.Source( "value1" ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "value1" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2145/Issue2145Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2145/Issue2145Mapper.java new file mode 100644 index 0000000000..f639f4e0dc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2145/Issue2145Mapper.java @@ -0,0 +1,85 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2145; + +import javax.xml.bind.JAXBElement; +import javax.xml.bind.annotation.XmlElementDecl; +import javax.xml.namespace.QName; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper( uses = Issue2145Mapper.ObjectFactory.class ) +public interface Issue2145Mapper { + + Issue2145Mapper INSTANCE = Mappers.getMapper( Issue2145Mapper.class ); + + @Mapping(target = "nested", source = "value") + Target map(Source source); + + default Nested map(String in) { + Nested nested = new Nested(); + nested.setValue( in ); + return nested; + } + + class Target { + + private JAXBElement nested; + + public JAXBElement getNested() { + return nested; + } + + public void setNested(JAXBElement nested) { + this.nested = nested; + } + } + + class Nested { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Source { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class ObjectFactory { + + private static final QName Q_NAME = new QName( "http://www.test.com/test", "" ); + private static final QName Q_NAME_NESTED = new QName( "http://www.test.com/test", "nested" ); + + @XmlElementDecl(namespace = "http://www.test.com/test", name = "Nested") + public JAXBElement createNested(Nested value) { + return new JAXBElement<>( Q_NAME, Nested.class, null, value ); + } + + @XmlElementDecl(namespace = "http://www.test.com/test", name = "nested", scope = Nested.class) + public JAXBElement createNestedInNestedTarget(Nested value) { + return new JAXBElement<>( Q_NAME_NESTED, Nested.class, Target.class, value ); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2145/Issue2145Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2145/Issue2145Test.java new file mode 100644 index 0000000000..38aed76003 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2145/Issue2145Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2145; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJavaxJaxb; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2145") +@WithClasses(Issue2145Mapper.class) +@WithJavaxJaxb +public class Issue2145Test { + + @ProcessorTest + public void test() { + Issue2145Mapper.Source source = new Issue2145Mapper.Source(); + source.setValue( "test" ); + + Issue2145Mapper.Target target = Issue2145Mapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getNested() ).isNotNull(); + assertThat( target.getNested().getScope() ).isEqualTo( Issue2145Mapper.Target.class ); + assertThat( target.getNested().getValue() ).isNotNull(); + assertThat( target.getNested().getValue().getValue() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2149/Erroneous2149Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2149/Erroneous2149Mapper.java new file mode 100644 index 0000000000..2b8d73cec2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2149/Erroneous2149Mapper.java @@ -0,0 +1,84 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2149; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Erroneous2149Mapper { + + @BeanMapping(ignoreByDefault = true) + @Mapping(target = ".", source = "name") + Target map(Source source); + + class Target { + + private String firstName; + private String age; + private String address; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getAge() { + return age; + } + + public void setAge(String age) { + this.age = age; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } + + class Source { + + private final String age; + private final Name name; + + public Source(String age, Name name) { + this.age = age; + this.name = name; + } + + public String getAge() { + return age; + } + + public Name getName() { + return name; + } + } + + class Name { + + private final String firstName; + + public Name(String firstName) { + this.firstName = firstName; + } + + public String getFirstName() { + return firstName; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2149/Issue2149Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2149/Issue2149Test.java new file mode 100644 index 0000000000..39c415f340 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2149/Issue2149Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2149; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2149") +@WithClasses({ + Erroneous2149Mapper.class +}) +public class Issue2149Test { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + type = Erroneous2149Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 18, + message = "Using @BeanMapping( ignoreByDefault = true ) with @Mapping( target = \".\", ... ) is not " + + "allowed. You'll need to explicitly ignore the target properties that should be ignored instead." + ) + } + ) + public void shouldGiveCompileErrorWhenBeanMappingIgnoreByDefaultIsCombinedWithMappingTargetThis() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java new file mode 100644 index 0000000000..7d152e88c1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Mapper.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2164; + +import java.math.BigDecimal; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2164Mapper { + + Issue2164Mapper INSTANCE = Mappers.getMapper( Issue2164Mapper.class ); + + @Mapping(target = "value", qualifiedByName = "truncate2") + Target map(BigDecimal value); + + @Named( "truncate2" ) + default String truncate2(String in) { + return in.substring( 0, 2 ); + } + + class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.java new file mode 100644 index 0000000000..5f7dc7f57f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2164/Issue2164Test.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2164; + +import java.math.BigDecimal; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2164") +@WithClasses(Issue2164Mapper.class) +public class Issue2164Test { + + @ProcessorTest + public void shouldSelectProperMethod() { + + Issue2164Mapper.Target target = Issue2164Mapper.INSTANCE.map( new BigDecimal( "1234" ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "12" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/Issue2170Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/Issue2170Test.java new file mode 100644 index 0000000000..b5c10d120a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/Issue2170Test.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170; + +import java.util.Collections; + +import org.mapstruct.ap.test.bugs._2170.dto.AddressDto; +import org.mapstruct.ap.test.bugs._2170.dto.PersonDto; +import org.mapstruct.ap.test.bugs._2170.entity.Address; +import org.mapstruct.ap.test.bugs._2170.entity.Person; +import org.mapstruct.ap.test.bugs._2170.mapper.AddressMapper; +import org.mapstruct.ap.test.bugs._2170.mapper.EntityMapper; +import org.mapstruct.ap.test.bugs._2170.mapper.PersonMapper; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2170") +@WithClasses({ + Address.class, + Person.class, + AddressDto.class, + PersonDto.class, + AddressMapper.class, + PersonMapper.class, + EntityMapper.class, +}) +public class Issue2170Test { + + @ProcessorTest + public void shouldGenerateCodeThatCompiles() { + + AddressDto addressDto = AddressMapper.INSTANCE.toDto( new Address( + "10000", + Collections.singletonList( new Person( "Tester" ) ) + ) ); + + assertThat( addressDto ).isNotNull(); + assertThat( addressDto.getZipCode() ).isEqualTo( "10000" ); + assertThat( addressDto.getPeople() ) + .extracting( PersonDto::getName ) + .containsExactly( "Tester" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/dto/AddressDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/dto/AddressDto.java new file mode 100644 index 0000000000..c0b9b06317 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/dto/AddressDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.dto; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class AddressDto { + + private final String zipCode; + private final List people; + + public AddressDto(String zipCode, + List people) { + this.zipCode = zipCode; + this.people = people; + } + + public String getZipCode() { + return zipCode; + } + + public List getPeople() { + return people; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/dto/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/dto/PersonDto.java new file mode 100644 index 0000000000..7e6d22e72a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/dto/PersonDto.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.dto; + +/** + * @author Filip Hrisafov + */ +public +class PersonDto { + + private final String name; + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/entity/Address.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/entity/Address.java new file mode 100644 index 0000000000..660ff0a260 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/entity/Address.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.entity; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class Address { + private final String zipCode; + private final List people; + + public Address(String zipCode, List people) { + this.zipCode = zipCode; + this.people = people; + } + + public String getZipCode() { + return zipCode; + } + + public List getPeople() { + return people; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/entity/Person.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/entity/Person.java new file mode 100644 index 0000000000..dc36699c5b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/entity/Person.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.entity; + +/** + * @author Filip Hrisafov + */ +public class Person { + private final String name; + + public Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/AddressMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/AddressMapper.java new file mode 100644 index 0000000000..e31937609e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/AddressMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2170.dto.AddressDto; +import org.mapstruct.ap.test.bugs._2170.entity.Address; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +//CHECKSTYLE:OFF +@Mapper(uses = { PersonMapper.class }) +//CHECKSTYLE:ON +public interface AddressMapper extends EntityMapper { + + AddressMapper INSTANCE = Mappers.getMapper( AddressMapper.class ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/EntityMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/EntityMapper.java new file mode 100644 index 0000000000..0f24b05483 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/EntityMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.mapper; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public interface EntityMapper { + E toEntity(D dto); + + D toDto(E entity); + + List toEntity(List dtoList); + + List toDto(List entityList); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/PersonMapper.java new file mode 100644 index 0000000000..28e7d0a31e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2170/mapper/PersonMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2170.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2170.dto.PersonDto; +import org.mapstruct.ap.test.bugs._2170.entity.Person; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface PersonMapper extends EntityMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/Issue2174Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/Issue2174Test.java new file mode 100644 index 0000000000..b6ec1f08d2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/Issue2174Test.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2174; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2174") +@WithClasses(UserMapper.class) +public class Issue2174Test { + + @ProcessorTest + public void shouldNotWrapCheckedException() throws Exception { + + UserMapper.User user = UserMapper.INSTANCE.map( new UserMapper.UserDto( "Test City", "10000" ) ); + + assertThat( user ).isNotNull(); + assertThat( user.getAddress() ).isNotNull(); + assertThat( user.getAddress().getCity() ).isNotNull(); + assertThat( user.getAddress().getCity().getName() ).isEqualTo( "Test City" ); + assertThat( user.getAddress().getCode() ).isNotNull(); + assertThat( user.getAddress().getCode().getCode() ).isEqualTo( "10000" ); + + assertThatThrownBy( () -> UserMapper.INSTANCE.map( new UserMapper.UserDto( "Zurich", "10000" ) ) ) + .isInstanceOf( UserMapper.CityNotFoundException.class ) + .hasMessage( "City with name 'Zurich' does not exist" ); + + assertThatThrownBy( () -> UserMapper.INSTANCE.map( new UserMapper.UserDto( "Test City", "1000" ) ) ) + .isInstanceOf( UserMapper.PostalCodeNotFoundException.class ) + .hasMessage( "Postal code '1000' does not exist" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/UserMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/UserMapper.java new file mode 100644 index 0000000000..025201b30c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/UserMapper.java @@ -0,0 +1,128 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2174; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface UserMapper { + + UserMapper INSTANCE = Mappers.getMapper( UserMapper.class ); + + @Mapping(target = "address.city", source = "city") + @Mapping(target = "address.code", source = "postalCode") + User map(UserDto dto) throws CityNotFoundException, PostalCodeNotFoundException; + + default City mapCity(String city) throws CityNotFoundException { + if ( "Test City".equals( city ) ) { + return new City( city ); + } + + throw new CityNotFoundException( "City with name '" + city + "' does not exist" ); + } + + default PostalCode mapCode(String code) throws PostalCodeNotFoundException { + if ( "10000".equals( code ) ) { + return new PostalCode( code ); + } + + throw new PostalCodeNotFoundException( "Postal code '" + code + "' does not exist" ); + } + + class UserDto { + private final String city; + private final String postalCode; + + public UserDto(String city, String postalCode) { + this.city = city; + this.postalCode = postalCode; + } + + public String getCity() { + return city; + } + + public String getPostalCode() { + return postalCode; + } + } + + class User { + + private final Address address; + + public User(Address address) { + this.address = address; + } + + public Address getAddress() { + return address; + } + } + + class Address { + private final City city; + private final PostalCode code; + + public Address(City city, PostalCode code) { + this.city = city; + this.code = code; + } + + public City getCity() { + return city; + } + + public PostalCode getCode() { + return code; + } + } + + class City { + + private final String name; + + public City(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class PostalCode { + + private final String code; + + public PostalCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + } + + class CityNotFoundException extends Exception { + + public CityNotFoundException(String message) { + super( message ); + } + } + + class PostalCodeNotFoundException extends Exception { + + public PostalCodeNotFoundException(String message) { + super( message ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2177/Issue2177Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2177/Issue2177Mapper.java new file mode 100644 index 0000000000..bf96c6b5b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2177/Issue2177Mapper.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2177; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2177Mapper { + + Issue2177Mapper INSTANCE = Mappers.getMapper( Issue2177Mapper.class ); + + Target map(Source source); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + private final T value; + + public Target(T value) { + this.value = value; + } + + public T getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2177/Issue2177Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2177/Issue2177Test.java new file mode 100644 index 0000000000..5c1c16b27f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2177/Issue2177Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2177; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2177") +@WithClasses({ + Issue2177Mapper.class +}) +public class Issue2177Test { + + @ProcessorTest + public void shouldCorrectlyUseGenericClassesWithConstructorMapping() { + + Issue2177Mapper.Target target = Issue2177Mapper.INSTANCE.map( new Issue2177Mapper.Source( "test" ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2185/Issue2185Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2185/Issue2185Test.java new file mode 100644 index 0000000000..7280d26e31 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2185/Issue2185Test.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2185; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2185") +@WithClasses({ + TodoMapper.class +}) +public class Issue2185Test { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = TodoMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 14, + message = "The mapper org.mapstruct.ap.test.bugs._2185.TodoMapper is referenced itself in Mapper#uses.") + } + ) + public void shouldCompile() { + + TodoMapper.TodoResponse response = TodoMapper.INSTANCE.toResponse( new TodoMapper.TodoEntity( "test" ) ); + + assertThat( response ).isNotNull(); + assertThat( response.getNote() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2185/TodoMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2185/TodoMapper.java new file mode 100644 index 0000000000..2d52bed1fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2185/TodoMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2185; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = TodoMapper.class) +public interface TodoMapper { + + TodoMapper INSTANCE = Mappers.getMapper( TodoMapper.class ); + + TodoResponse toResponse(TodoEntity entity); + + class TodoResponse { + + private final String note; + + public TodoResponse(String note) { + this.note = note; + } + + public String getNote() { + return note; + } + } + + class TodoEntity { + + private final String note; + + public TodoEntity(String note) { + this.note = note; + } + + public String getNote() { + return note; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/Issue2195Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/Issue2195Mapper.java new file mode 100644 index 0000000000..cde09dd2e3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/Issue2195Mapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2195; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2195.dto.Source; +import org.mapstruct.ap.test.bugs._2195.dto.Target; +import org.mapstruct.ap.test.bugs._2195.dto.TargetBase; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2195Mapper { + + Issue2195Mapper INSTANCE = Mappers.getMapper( Issue2195Mapper.class ); + + @BeanMapping( resultType = Target.class ) + TargetBase map(Source source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/Issue2195Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/Issue2195Test.java new file mode 100644 index 0000000000..5ee3c35d86 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/Issue2195Test.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2195; + +import org.mapstruct.ap.test.bugs._2195.dto.Source; +import org.mapstruct.ap.test.bugs._2195.dto.Target; +import org.mapstruct.ap.test.bugs._2195.dto.TargetBase; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2195") +@WithClasses( { Source.class, Target.class, TargetBase.class } ) +public class Issue2195Test { + + @ProcessorTest + @WithClasses( Issue2195Mapper.class ) + public void test() { + + Source source = new Source(); + source.setName( "JohnDoe" ); + + TargetBase target = Issue2195Mapper.INSTANCE.map( source ); + + assertThat( target ).isInstanceOf( Target.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/Source.java new file mode 100644 index 0000000000..78a4bba1a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/Source.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2195.dto; + +public class Source { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/Target.java new file mode 100644 index 0000000000..8a74d44104 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/Target.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2195.dto; + +public class Target extends TargetBase { + + protected Target(Builder builder) { + super( builder ); + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder extends TargetBase.Builder { + + protected Builder() { + } + + public Target build() { + return new Target( this ); + } + + public Builder name(String name) { + return this; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/TargetBase.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/TargetBase.java new file mode 100644 index 0000000000..ffb2eff2bc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2195/dto/TargetBase.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2195.dto; + +public class TargetBase { + + private final String name; + + protected TargetBase(Builder builder) { + this.name = builder.name; + } + + public static Builder builder() { + return new Builder(); + } + + public String getName() { + return name; + } + + public static class Builder { + + protected Builder() { + } + + private String name; + + public TargetBase build() { + return new TargetBase( this ); + } + + public Builder name(String name) { + this.name = name; + return this; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2197/Issue2197Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2197/Issue2197Mapper.java new file mode 100644 index 0000000000..def6f8f601 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2197/Issue2197Mapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2197; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2197Mapper { + + Issue2197Mapper INSTANCE = Mappers.getMapper( Issue2197Mapper.class ); + + _0Target map(Source source); + + // CHECKSTYLE:OFF + class _0Target { + // CHECKSTYLE:ON + private final String value; + + public _0Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2197/Issue2197Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2197/Issue2197Test.java new file mode 100644 index 0000000000..774d1f396f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2197/Issue2197Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2197; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2197") +@WithClasses(Issue2197Mapper.class) +public class Issue2197Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( Issue2197Mapper.class ); + + @ProcessorTest + public void underscoreAndDigitPrefixShouldBeStrippedFromGeneratedLocalVariables() { + Issue2197Mapper._0Target target = Issue2197Mapper.INSTANCE.map( new Issue2197Mapper.Source( "value1" ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "value1" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Car.java new file mode 100755 index 0000000000..4f2ec92af6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Car.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2213; + +public class Car { + private int[] intData; + private Long[] longData; + + public int[] getIntData() { + return intData; + } + + public void setIntData(int[] intData) { + this.intData = intData; + } + + public Long[] getLongData() { + return longData; + } + + public void setLongData(Long[] longData) { + this.longData = longData; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Car2.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Car2.java new file mode 100755 index 0000000000..ec0cd6de6d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Car2.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2213; + +public class Car2 { + private int[] intData; + private Long[] longData; + + public @NotNull int[] getIntData() { + return intData; + } + + public void setIntData(int[] intData) { + this.intData = intData; + } + + public @NotNull Long[] getLongData() { + return longData; + } + + public void setLongData(Long[] longData) { + this.longData = longData; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/CarMapper.java new file mode 100644 index 0000000000..f3b25c0213 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/CarMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2213; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(mappingControl = DeepClone.class) +public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + Car toCar(Car2 car2); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Issue2213Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Issue2213Test.java new file mode 100644 index 0000000000..2f8f951668 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/Issue2213Test.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2213; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + NotNull.class, + CarMapper.class, + Car.class, + Car2.class +}) +@IssueKey("2213") +public class Issue2213Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( CarMapper.class ); + + @ProcessorTest + public void testShouldNotGenerateIntermediatePrimitiveMappingMethod() { + Car2 car = new Car2(); + int[] sourceInt = { 1, 2, 3 }; + car.setIntData( sourceInt ); + Long[] sourceLong = { 1L, 2L, 3L }; + car.setLongData( sourceLong ); + Car target = CarMapper.INSTANCE.toCar( car ); + + assertThat( target ).isNotNull(); + assertThat( target.getIntData() ) + .containsExactly( 1, 2, 3 ) + .isNotSameAs( sourceInt ); + assertThat( target.getLongData() ) + .containsExactly( 1L, 2L, 3L ) + .isNotSameAs( sourceLong ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/NotNull.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/NotNull.java new file mode 100644 index 0000000000..3b45f03ed4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2213/NotNull.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2213; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ + ElementType.METHOD, + ElementType.TYPE_USE +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface NotNull { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/Issue2221Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/Issue2221Test.java new file mode 100644 index 0000000000..ef7f2f4ba6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/Issue2221Test.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2221; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2221") +@WithClasses({ + RestConfig.class, + RestSiteDto.class, + RestSiteMapper.class, + SiteDto.class, +}) +public class Issue2221Test { + + @ProcessorTest + public void multiSourceInheritConfigurationShouldWork() { + SiteDto site = RestSiteMapper.INSTANCE.convert( + new RestSiteDto( "restTenant", "restSite", "restCti" ), + "parameterTenant", + "parameterSite" + ); + + assertThat( site ).isNotNull(); + assertThat( site.getTenantId() ).isEqualTo( "parameterTenant" ); + assertThat( site.getSiteId() ).isEqualTo( "parameterSite" ); + assertThat( site.getCtiId() ).isEqualTo( "restCti" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestConfig.java new file mode 100644 index 0000000000..9a0f79f82d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestConfig.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2221; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; + +/** + * @author Filip Hrisafov + */ +@MapperConfig +public interface RestConfig { + + @Mapping(target = "tenantId", source = "tenantId") + @Mapping(target = "siteId", source = "siteId") + @Mapping(target = "ctiId", source = "source.cti", defaultValue = "unknown") + SiteDto convert(RestSiteDto source, String tenantId, String siteId); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestSiteDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestSiteDto.java new file mode 100644 index 0000000000..eb1a56b344 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestSiteDto.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2221; + +/** + * @author Filip Hrisafov + */ +public class RestSiteDto { + + private final String tenantId; + private final String siteId; + private final String cti; + + public RestSiteDto(String tenantId, String siteId, String cti) { + this.tenantId = tenantId; + this.siteId = siteId; + this.cti = cti; + } + + public String getTenantId() { + return tenantId; + } + + public String getSiteId() { + return siteId; + } + + public String getCti() { + return cti; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestSiteMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestSiteMapper.java new file mode 100644 index 0000000000..cf7281f44f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/RestSiteMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2221; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(config = RestConfig.class) +public interface RestSiteMapper { + + RestSiteMapper INSTANCE = Mappers.getMapper( RestSiteMapper.class ); + + @InheritConfiguration + SiteDto convert(RestSiteDto source, String tenantId, String siteId); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/SiteDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/SiteDto.java new file mode 100644 index 0000000000..7c80410029 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2221/SiteDto.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2221; + +/** + * @author Filip Hrisafov + */ +public class SiteDto { + + private final String tenantId; + private final String siteId; + private final String ctiId; + + public SiteDto(String tenantId, String siteId, String ctiId) { + this.tenantId = tenantId; + this.siteId = siteId; + this.ctiId = ctiId; + } + + public String getTenantId() { + return tenantId; + } + + public String getSiteId() { + return siteId; + } + + public String getCtiId() { + return ctiId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/Issue2233Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/Issue2233Test.java new file mode 100644 index 0000000000..66911d936d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/Issue2233Test.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2233; + +import java.util.Collections; +import java.util.Optional; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2233") +@WithClasses( { + Program.class, + ProgramAggregate.class, + ProgramDto.class, + ProgramMapper.class, + ProgramResponseDto.class, +} ) +public class Issue2233Test { + + @ProcessorTest + public void shouldCorrectlyMapFromOptionalToCollection() { + ProgramResponseDto response = ProgramMapper.INSTANCE.map( new ProgramAggregate( Collections.singleton( + new Program( + "Optional Mapping", + "123" + ) ) ) ); + + assertThat( response ).isNotNull(); + assertThat( response.getPrograms() ).isPresent(); + assertThat( response.getPrograms().get() ) + .extracting( ProgramDto::getName, ProgramDto::getNumber ) + .containsExactly( + tuple( Optional.of( "Optional Mapping" ), Optional.of( "123" ) ) + ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/Program.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/Program.java new file mode 100644 index 0000000000..748ad4901c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/Program.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2233; + +import java.util.Optional; + +/** + * @author Filip Hrisafov + */ +public class Program { + + private final String name; + private final String number; + + public Program(String name, String number) { + this.name = name; + this.number = number; + } + + public Optional getName() { + return Optional.ofNullable( name ); + } + + public Optional getNumber() { + return Optional.ofNullable( number ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramAggregate.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramAggregate.java new file mode 100644 index 0000000000..c3fdabe151 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramAggregate.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2233; + +import java.util.Collection; +import java.util.Optional; + +/** + * @author Filip Hrisafov + */ +public class ProgramAggregate { + + private final Collection programs; + + public ProgramAggregate(Collection programs) { + this.programs = programs; + } + + public Optional> getPrograms() { + return Optional.ofNullable( programs ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramDto.java new file mode 100644 index 0000000000..d567998667 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramDto.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2233; + +import java.util.Optional; + +/** + * @author Filip Hrisafov + */ +public class ProgramDto { + + private final String name; + private final String number; + + public ProgramDto(String name, String number) { + this.name = name; + this.number = number; + } + + public Optional getName() { + return Optional.ofNullable( name ); + } + + public Optional getNumber() { + return Optional.ofNullable( number ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramMapper.java new file mode 100644 index 0000000000..e2737f8e3b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2233; + +import java.util.Collection; +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ProgramMapper { + + ProgramMapper INSTANCE = Mappers.getMapper( ProgramMapper.class ); + + ProgramResponseDto map(ProgramAggregate programAggregate); + + ProgramDto map(Program sourceProgramDto); + + Collection mapPrograms(Collection sourcePrograms); + + default T fromOptional(Optional optional) { + return optional.orElse( null ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramResponseDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramResponseDto.java new file mode 100644 index 0000000000..61e7df4d00 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2233/ProgramResponseDto.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2233; + +import java.util.Collection; +import java.util.Optional; + +/** + * @author Filip Hrisafov + */ +public class ProgramResponseDto { + + private final Collection programs; + + public ProgramResponseDto(Collection programs) { + this.programs = programs; + } + + public Optional> getPrograms() { + return Optional.ofNullable( programs ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Car.java new file mode 100644 index 0000000000..70bb9a413c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Car.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2236; + +/** + * @author Filip Hrisafov + */ +public class Car { + + private String name; + private String type; + private Owner ownerA; + private Owner ownerB; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Owner getOwnerA() { + return ownerA; + } + + public void setOwnerA(Owner ownerA) { + this.ownerA = ownerA; + } + + public Owner getOwnerB() { + return ownerB; + } + + public void setOwnerB(Owner ownerB) { + this.ownerB = ownerB; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/CarDto.java new file mode 100644 index 0000000000..909bb3649b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/CarDto.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2236; + +/** + * @author Filip Hrisafov + */ +public class CarDto { + + private String name; + private String ownerNameA; + private String ownerNameB; + private String ownerCityA; + private String ownerCityB; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOwnerNameA() { + return ownerNameA; + } + + public void setOwnerNameA(String ownerNameA) { + this.ownerNameA = ownerNameA; + } + + public String getOwnerNameB() { + return ownerNameB; + } + + public void setOwnerNameB(String ownerNameB) { + this.ownerNameB = ownerNameB; + } + + public String getOwnerCityA() { + return ownerCityA; + } + + public void setOwnerCityA(String ownerCityA) { + this.ownerCityA = ownerCityA; + } + + public String getOwnerCityB() { + return ownerCityB; + } + + public void setOwnerCityB(String ownerCityB) { + this.ownerCityB = ownerCityB; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/CarMapper.java new file mode 100644 index 0000000000..d3366ea2a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/CarMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2236; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CarMapper { + + CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); + + @Mapping(target = "ownerA.name", source = "carDto.ownerNameA") + @Mapping(target = "ownerA.city", source = "carDto.ownerCityA") + @Mapping(target = "ownerB.name", source = "carDto.ownerNameB") + @Mapping(target = "ownerB.city", source = "carDto.ownerCityB") + @Mapping(target = "name", source = "carDto.name") + @Mapping(target = "type", source = "type") + Car vehicleToCar(Vehicle vehicle); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Issue2236Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Issue2236Test.java new file mode 100644 index 0000000000..a1bbea638b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Issue2236Test.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2236; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2236") +@WithClasses({ + Car.class, + CarDto.class, + CarMapper.class, + Owner.class, + Vehicle.class, +}) +public class Issue2236Test { + + @ProcessorTest + public void shouldCorrectlyMapSameTypesWithDifferentNestedMappings() { + + Vehicle vehicle = new Vehicle(); + vehicle.setType( "Sedan" ); + CarDto carDto = new CarDto(); + vehicle.setCarDto( carDto ); + + carDto.setName( "Private car" ); + carDto.setOwnerNameA( "Owner A" ); + carDto.setOwnerCityA( "Zurich" ); + + carDto.setOwnerNameB( "Owner B" ); + carDto.setOwnerCityB( "Bern" ); + + Car car = CarMapper.INSTANCE.vehicleToCar( vehicle ); + + assertThat( car ).isNotNull(); + assertThat( car.getType() ).isEqualTo( "Sedan" ); + assertThat( car.getName() ).isEqualTo( "Private car" ); + assertThat( car.getOwnerA() ).isNotNull(); + assertThat( car.getOwnerA().getName() ).isEqualTo( "Owner A" ); + assertThat( car.getOwnerA().getCity() ).isEqualTo( "Zurich" ); + assertThat( car.getOwnerB() ).isNotNull(); + assertThat( car.getOwnerB().getName() ).isEqualTo( "Owner B" ); + assertThat( car.getOwnerB().getCity() ).isEqualTo( "Bern" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Owner.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Owner.java new file mode 100644 index 0000000000..5f200f527a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Owner.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2236; + +/** + * @author Filip Hrisafov + */ +public class Owner { + + private String name; + private String city; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Vehicle.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Vehicle.java new file mode 100644 index 0000000000..fc8e744e82 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2236/Vehicle.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2236; + +/** + * @author Filip Hrisafov + */ +public class Vehicle { + private CarDto carDto; + private String type; + + public CarDto getCarDto() { + return carDto; + } + + public void setCarDto(CarDto carDto) { + this.carDto = carDto; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2245/Issue2245Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2245/Issue2245Test.java new file mode 100644 index 0000000000..69af6fef8a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2245/Issue2245Test.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2245; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2245") +@WithClasses({ + TestMapper.class +}) +public class Issue2245Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( TestMapper.class ); + + @ProcessorTest + public void shouldGenerateSourceGetMethodOnce() { + + TestMapper.Tenant tenant = + TestMapper.INSTANCE.map( new TestMapper.TenantDTO( new TestMapper.Inner( "acme" ) ) ); + + assertThat( tenant ).isNotNull(); + assertThat( tenant.getId() ).isEqualTo( "acme" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2245/TestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2245/TestMapper.java new file mode 100644 index 0000000000..750ee12fa5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2245/TestMapper.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2245; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface TestMapper { + + TestMapper INSTANCE = Mappers.getMapper( TestMapper.class ); + + class Tenant { + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + } + + class Inner { + private final String id; + + public Inner(String id) { + this.id = id; + } + + public String getId() { + return id; + } + } + + class TenantDTO { + private final Inner inner; + + public TenantDTO(Inner inner) { + this.inner = inner; + } + + public Inner getInner() { + return inner; + } + } + + @Mapping(target = "id", source = "inner.id", defaultValue = "test") + Tenant map(TenantDTO tenant); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Issue2251Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Issue2251Mapper.java new file mode 100644 index 0000000000..d09f3440fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Issue2251Mapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2251; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2251Mapper { + + Issue2251Mapper INSTANCE = Mappers.getMapper( Issue2251Mapper.class ); + + @Mapping(target = "value1", source = "source.value") + Target map(Source source, String value2); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Issue2251Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Issue2251Test.java new file mode 100644 index 0000000000..1c430b00ca --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Issue2251Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2251; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2251") +@WithClasses({ + Issue2251Mapper.class, + Source.class, + Target.class, +}) +public class Issue2251Test { + + @ProcessorTest + public void shouldGenerateCorrectCode() { + + Target target = Issue2251Mapper.INSTANCE.map( new Source( "source" ), "test" ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue1() ).isEqualTo( "source" ); + assertThat( target.getValue2() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Source.java new file mode 100644 index 0000000000..cbd882a8f8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2251; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Target.java new file mode 100644 index 0000000000..363129797f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2251/Target.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2251; + +public class Target { + private final String value1; + private final String value2; + + public Target(String value1, String value2) { + this.value1 = value1; + this.value2 = value2; + } + + public String getValue1() { + return value1; + } + + public String getValue2() { + return value2; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java new file mode 100644 index 0000000000..ae1c1eea79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/Issue2253Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2253; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2253") +@WithClasses( { + TestMapper.class, +} ) +public class Issue2253Test { + + @ProcessorTest + public void shouldNotTreatMatchedSourceParameterAsBean() { + + TestMapper.Person person = TestMapper.INSTANCE.map( new TestMapper.PersonDto( 20 ), "Tester" ); + + assertThat( person.getAge() ).isEqualTo( 20 ); + assertThat( person.getName() ).isEqualTo( "Tester" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java new file mode 100644 index 0000000000..1e05e444a2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2253/TestMapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2253; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface TestMapper { + + TestMapper INSTANCE = Mappers.getMapper( TestMapper.class ); + + Person map(PersonDto personDto, String name); + + class Person { + private final int age; + private final String name; + + public Person(int age, String name) { + this.age = age; + this.name = name; + } + + public int getAge() { + return age; + } + + public String getName() { + return name; + } + } + + class PersonDto { + private final int age; + + public PersonDto(int age) { + this.age = age; + } + + public int getAge() { + return age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Erroneous2263Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Erroneous2263Mapper.java new file mode 100644 index 0000000000..59a0a42ddb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Erroneous2263Mapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2263; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Erroneous2263Mapper { + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Issue2263Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Issue2263Test.java new file mode 100644 index 0000000000..53fd5d88a4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Issue2263Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2263; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2263") +@WithClasses({ + Erroneous2263Mapper.class, + Source.class, + Target.class, +}) +public class Issue2263Test { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = Erroneous2263Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Can't map property \"Object value\" to \"String value\". " + + "Consider to declare/implement a mapping method: \"String map(Object value)\".") + }) + public void shouldCorrectlyReportUnmappableTargetObject() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Source.java new file mode 100644 index 0000000000..54e5b7fd38 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2263; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final Object value; + + public Source(Object value) { + this.value = value; + } + + public Object getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Target.java new file mode 100644 index 0000000000..943a51264c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2263/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2263; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278MapperA.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278MapperA.java new file mode 100644 index 0000000000..8527be3f89 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278MapperA.java @@ -0,0 +1,62 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2278; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * ReproducerA + * + */ +@Mapper +public interface Issue2278MapperA { + + Issue2278MapperA INSTANCE = Mappers.getMapper( Issue2278MapperA.class ); + + @Mapping( target = "detailsDTO", source = "details" ) + @Mapping( target = "detailsDTO.fuelType", ignore = true ) + CarDTO map(Car in); + + // checkout the Issue2278ReferenceMapper, the @InheritInverseConfiguration + // is de-facto @Mapping( target = "details", source = "detailsDTO" ) + @InheritInverseConfiguration + @Mapping( target = "details.model", ignore = true ) + @Mapping( target = "details.type", constant = "gto") + @Mapping( target = "details.fuel", source = "detailsDTO.fuelType") + Car map(CarDTO in); + + class Car { + //CHECKSTYLE:OFF + public Details details; + //CHECKSTYLE:ON + } + + class CarDTO { + //CHECKSTYLE:OFF + public DetailsDTO detailsDTO; + //CHECKSTYLE:ON + } + + class Details { + //CHECKSTYLE:OFF + public String brand; + public String model; + public String type; + public String fuel; + //CHECKSTYLE:ON + } + + class DetailsDTO { + //CHECKSTYLE:OFF + public String brand; + public String fuelType; + //CHECKSTYLE:ON + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278MapperB.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278MapperB.java new file mode 100644 index 0000000000..b9d0abd523 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278MapperB.java @@ -0,0 +1,65 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2278; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * ReproducerB + * + */ +@Mapper +public interface Issue2278MapperB { + + Issue2278MapperB INSTANCE = Mappers.getMapper( Issue2278MapperB.class ); + + // id mapping is cros-linked + @Mapping( target = "amount", source = "price" ) + @Mapping( target = "detailsDTO.brand", source = "details.type" ) + @Mapping( target = "detailsDTO.id1", source = "details.id2" ) + @Mapping( target = "detailsDTO.id2", source = "details.id1" ) + CarDTO map(Car in); + + // inherit inverse, but undo cross-link in one sweep + @InheritInverseConfiguration // inherits all + @Mapping( target = "details", source = "detailsDTO" ) // resets everything on details <> detailsDto + @Mapping( target = "details.type", source = "detailsDTO.brand" ) // so this needs to be redone + Car map2(CarDTO in); + + class Car { + //CHECKSTYLE:OFF + public float price; + public Details details; + //CHECKSTYLE:ON + } + + class CarDTO { + //CHECKSTYLE:OFF + public float amount; + public DetailsDTO detailsDTO; + //CHECKSTYLE:ON + } + + class Details { + //CHECKSTYLE:OFF + public String type; + public String id1; + public String id2; + //CHECKSTYLE:ON + } + + class DetailsDTO { + //CHECKSTYLE:OFF + public String brand; + public String id1; + public String id2; + //CHECKSTYLE:ON + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278ReferenceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278ReferenceMapper.java new file mode 100644 index 0000000000..48b457f84c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278ReferenceMapper.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2278; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * A reference mapper, that checks how a regular forward merge works + */ +@Mapper +public interface Issue2278ReferenceMapper { + + Issue2278ReferenceMapper INSTANCE = Mappers.getMapper( Issue2278ReferenceMapper.class ); + + @Mapping( target = "details", source = "detailsDTO" ) + @Mapping( target = "details.model", ignore = true ) + @Mapping( target = "details.type", constant = "gto") + @Mapping( target = "details.fuel", source = "detailsDTO.fuelType") + Car map(CarDTO in); + + class Car { + //CHECKSTYLE:OFF + public Details details; + //CHECKSTYLE:ON + } + + class CarDTO { + //CHECKSTYLE:OFF + public DetailsDTO detailsDTO; + //CHECKSTYLE:ON + } + + class Details { + //CHECKSTYLE:OFF + public String brand; + public String model; + public String type; + public String fuel; + //CHECKSTYLE:ON + } + + class DetailsDTO { + //CHECKSTYLE:OFF + public String brand; + public String fuelType; + //CHECKSTYLE:ON + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278Test.java new file mode 100644 index 0000000000..7289da4ff1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2278/Issue2278Test.java @@ -0,0 +1,92 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2278; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2278") +public class Issue2278Test { + + @ProcessorTest + @WithClasses( Issue2278ReferenceMapper.class ) + public void testReferenceMergeBehaviour() { + + Issue2278ReferenceMapper.CarDTO dto = new Issue2278ReferenceMapper.CarDTO(); + dto.detailsDTO = new Issue2278ReferenceMapper.DetailsDTO(); + dto.detailsDTO.brand = "Ford"; + dto.detailsDTO.fuelType = "petrol"; + + Issue2278ReferenceMapper.Car target = Issue2278ReferenceMapper.INSTANCE.map( dto ); + + assertThat( target ).isNotNull(); + assertThat( target.details ).isNotNull(); + assertThat( target.details.brand ).isEqualTo( "Ford" ); + assertThat( target.details.model ).isNull(); + assertThat( target.details.type ).isEqualTo( "gto" ); + assertThat( target.details.fuel ).isEqualTo( "petrol" ); + + } + + @ProcessorTest + @WithClasses( Issue2278MapperA.class ) + public void shouldBehaveJustAsTestReferenceMergeBehaviour() { + + Issue2278MapperA.CarDTO dto = new Issue2278MapperA.CarDTO(); + dto.detailsDTO = new Issue2278MapperA.DetailsDTO(); + dto.detailsDTO.brand = "Ford"; + dto.detailsDTO.fuelType = "petrol"; + + Issue2278MapperA.Car target = Issue2278MapperA.INSTANCE.map( dto ); + + assertThat( target ).isNotNull(); + assertThat( target.details ).isNotNull(); + assertThat( target.details.brand ).isEqualTo( "Ford" ); + assertThat( target.details.model ).isNull(); + assertThat( target.details.type ).isEqualTo( "gto" ); + assertThat( target.details.fuel ).isEqualTo( "petrol" ); + + } + + @ProcessorTest + @WithClasses( Issue2278MapperB.class ) + public void shouldOverrideDetailsMappingWithRedefined() { + + Issue2278MapperB.Car source = new Issue2278MapperB.Car(); + source.details = new Issue2278MapperB.Details(); + source.details.type = "Ford"; + source.details.id1 = "id1"; + source.details.id2 = "id2"; + source.price = 20000f; + + Issue2278MapperB.CarDTO target1 = Issue2278MapperB.INSTANCE.map( source ); + + assertThat( target1 ).isNotNull(); + assertThat( target1.amount ).isEqualTo( 20000f ); + assertThat( target1.detailsDTO ).isNotNull(); + assertThat( target1.detailsDTO.brand ).isEqualTo( "Ford" ); + assertThat( target1.detailsDTO.id1 ).isEqualTo( "id2" ); + assertThat( target1.detailsDTO.id2 ).isEqualTo( "id1" ); + + // restore the mappings, just to make it logical again + target1.detailsDTO.id1 = "id1"; + target1.detailsDTO.id2 = "id2"; + + // now check the reverse inheritance + Issue2278MapperB.Car target2 = Issue2278MapperB.INSTANCE.map2( target1 ); + + assertThat( target2 ).isNotNull(); + assertThat( target2.price ).isEqualTo( 20000f ); + assertThat( target2.details ).isNotNull(); + assertThat( target2.details.type ).isEqualTo( "Ford" ); // should inherit + assertThat( target2.details.id1 ).isEqualTo( "id1" ); // should be undone + assertThat( target2.details.id2 ).isEqualTo( "id2" ); // should be undone + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Artifact.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Artifact.java new file mode 100644 index 0000000000..316959f48b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Artifact.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2301; + +import java.util.Set; + +/** + * @author Filip Hrisafov + */ +public class Artifact { + + private String name; + private Set dependantBuildRecords; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Set getDependantBuildRecords() { + return dependantBuildRecords; + } + + public void setDependantBuildRecords(Set dependantBuildRecords) { + this.dependantBuildRecords = dependantBuildRecords; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String name; + private Set dependantBuildRecords; + + public Artifact build() { + Artifact artifact = new Artifact(); + artifact.setName( name ); + artifact.setDependantBuildRecords( dependantBuildRecords ); + + return artifact; + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder dependantBuildRecord(String dependantBuildRecord) { + this.dependantBuildRecords.add( dependantBuildRecord ); + return this; + } + + public Builder dependantBuildRecords(Set dependantBuildRecords) { + this.dependantBuildRecords = dependantBuildRecords; + return this; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/ArtifactDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/ArtifactDto.java new file mode 100644 index 0000000000..68b9280930 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/ArtifactDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2301; + +/** + * @author Filip Hrisafov + */ +public class ArtifactDto { + + private final String name; + + public ArtifactDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Issue2301Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Issue2301Mapper.java new file mode 100644 index 0000000000..cd3cca3744 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Issue2301Mapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2301; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2301Mapper { + + Issue2301Mapper INSTANCE = Mappers.getMapper( Issue2301Mapper.class ); + + @Mapping(target = "dependantBuildRecords", ignore = true) + @Mapping(target = "dependantBuildRecord", ignore = true) + Artifact map(ArtifactDto dto); + + @InheritConfiguration + void update(@MappingTarget Artifact artifact, ArtifactDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Issue2301Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Issue2301Test.java new file mode 100644 index 0000000000..3986ab1066 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2301/Issue2301Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2301; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2301") +@WithClasses({ + Artifact.class, + ArtifactDto.class, + Issue2301Mapper.class +}) +public class Issue2301Test { + + @ProcessorTest + public void shouldCorrectlyIgnoreProperties() { + Artifact artifact = Issue2301Mapper.INSTANCE.map( new ArtifactDto( "mapstruct" ) ); + + assertThat( artifact ).isNotNull(); + assertThat( artifact.getName() ).isEqualTo( "mapstruct" ); + assertThat( artifact.getDependantBuildRecords() ).isNull(); + + Issue2301Mapper.INSTANCE.update( artifact, new ArtifactDto( "mapstruct-processor" ) ); + + assertThat( artifact.getName() ).isEqualTo( "mapstruct-processor" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2318/Issue2318Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2318/Issue2318Mapper.java new file mode 100644 index 0000000000..20621e4d01 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2318/Issue2318Mapper.java @@ -0,0 +1,115 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2318; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper(config = Issue2318Mapper.Config.class) +public interface Issue2318Mapper { + + Issue2318Mapper INSTANCE = Mappers.getMapper( Issue2318Mapper.class ); + + @MapperConfig + interface Config { + + @Mapping(target = "parentValue1", source = "holder") + TargetParent mapParent(SourceParent parent); + + @InheritConfiguration(name = "mapParent") + @Mapping(target = "childValue", source = "value") + @Mapping(target = "parentValue2", source = "holder.parentValue2") + TargetChild mapChild(SourceChild child); + } + + @InheritConfiguration(name = "mapChild") + TargetChild mapChild(SourceChild child); + + default String parentValue1(SourceParent.Holder holder) { + return holder.getParentValue1(); + } + + class SourceParent { + private Holder holder; + + public Holder getHolder() { + return holder; + } + + public void setHolder(Holder holder) { + this.holder = holder; + } + + public static class Holder { + private String parentValue1; + private Integer parentValue2; + + public String getParentValue1() { + return parentValue1; + } + + public void setParentValue1(String parentValue1) { + this.parentValue1 = parentValue1; + } + + public Integer getParentValue2() { + return parentValue2; + } + + public void setParentValue2(Integer parentValue2) { + this.parentValue2 = parentValue2; + } + } + } + + class SourceChild extends SourceParent { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class TargetParent { + private String parentValue1; + private Integer parentValue2; + + public String getParentValue1() { + return parentValue1; + } + + public void setParentValue1(String parentValue1) { + this.parentValue1 = parentValue1; + } + + public Integer getParentValue2() { + return parentValue2; + } + + public void setParentValue2(Integer parentValue2) { + this.parentValue2 = parentValue2; + } + } + + class TargetChild extends TargetParent { + private String childValue; + + public String getChildValue() { + return childValue; + } + + public void setChildValue(String childValue) { + this.childValue = childValue; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2318/Issue2318Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2318/Issue2318Test.java new file mode 100644 index 0000000000..a9a06ea470 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2318/Issue2318Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2318; + +import org.mapstruct.ap.test.bugs._2318.Issue2318Mapper.SourceChild; +import org.mapstruct.ap.test.bugs._2318.Issue2318Mapper.TargetChild; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("2318") +public class Issue2318Test { + + @ProcessorTest + @WithClasses( Issue2318Mapper.class ) + public void shouldMap() { + + SourceChild source = new SourceChild(); + source.setValue( "From child" ); + source.setHolder( new Issue2318Mapper.SourceParent.Holder() ); + source.getHolder().setParentValue1( "From parent" ); + source.getHolder().setParentValue2( 12 ); + + TargetChild target = Issue2318Mapper.INSTANCE.mapChild( source ); + + assertThat( target.getParentValue1() ).isEqualTo( "From parent" ); + assertThat( target.getParentValue2() ).isEqualTo( 12 ); + assertThat( target.getChildValue() ).isEqualTo( "From child" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2347/ErroneousClassWithPrivateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2347/ErroneousClassWithPrivateMapper.java new file mode 100644 index 0000000000..c18620887e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2347/ErroneousClassWithPrivateMapper.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2347; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +public class ErroneousClassWithPrivateMapper { + + public static class Target { + private final String id; + + public Target(String id) { + this.id = id; + } + + public String getId() { + return id; + } + } + + public static class Source { + + private final String id; + + public Source(String id) { + this.id = id; + } + + public String getId() { + return id; + } + } + + @Mapper + private interface PrivateInterfaceMapper { + + Target map(Source source); + } + + @Mapper + private abstract class PrivateClassMapper { + + public abstract Target map(Source source); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2347/Issue2347Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2347/Issue2347Test.java new file mode 100644 index 0000000000..e54816d576 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2347/Issue2347Test.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2347; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2347") +@WithClasses({ + ErroneousClassWithPrivateMapper.class +}) +public class Issue2347Test { + + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + type = ErroneousClassWithPrivateMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 41, + message = "Cannot create an implementation for mapper PrivateInterfaceMapper," + + " because it is a private interface." + ), + @Diagnostic( + type = ErroneousClassWithPrivateMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 47, + message = "Cannot create an implementation for mapper PrivateClassMapper," + + " because it is a private class." + ) + } + ) + @ProcessorTest + public void shouldGenerateCompileErrorWhenMapperIsPrivate() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/Issue2352Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/Issue2352Test.java new file mode 100644 index 0000000000..fa9edf0bf4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/Issue2352Test.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2352; + +import java.util.List; + +import org.mapstruct.ap.test.bugs._2352.dto.TheDto; +import org.mapstruct.ap.test.bugs._2352.dto.TheModel; +import org.mapstruct.ap.test.bugs._2352.dto.TheModels; +import org.mapstruct.ap.test.bugs._2352.mapper.TheModelMapper; +import org.mapstruct.ap.test.bugs._2352.mapper.TheModelsMapper; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2352") +@WithClasses({ + TheDto.class, + TheModel.class, + TheModels.class, + TheModelMapper.class, + TheModelsMapper.class, +}) +public class Issue2352Test { + + @ProcessorTest + public void shouldGenerateValidCode() { + TheModels theModels = new TheModels(); + theModels.add( new TheModel( "1" ) ); + theModels.add( new TheModel( "2" ) ); + + List theDtos = TheModelsMapper.INSTANCE.convert( theModels ); + + assertThat( theDtos ) + .extracting( TheDto::getId ) + .containsExactly( "1", "2" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheDto.java new file mode 100644 index 0000000000..a07c8bd093 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2352.dto; + +/** + * @author Filip Hrisafov + */ +public class TheDto { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheModel.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheModel.java new file mode 100644 index 0000000000..fc7b1e89be --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheModel.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2352.dto; + +/** + * @author Filip Hrisafov + */ +public class TheModel { + + private final String id; + + public TheModel(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheModels.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheModels.java new file mode 100644 index 0000000000..37359ce779 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/dto/TheModels.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2352.dto; + +import java.util.ArrayList; + +/** + * @author Filip Hrisafov + */ +public class TheModels extends ArrayList { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/mapper/TheModelMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/mapper/TheModelMapper.java new file mode 100644 index 0000000000..2e9b5be478 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/mapper/TheModelMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2352.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2352.dto.TheDto; +import org.mapstruct.ap.test.bugs._2352.dto.TheModel; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface TheModelMapper { + + TheDto convert(TheModel theModel); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/mapper/TheModelsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/mapper/TheModelsMapper.java new file mode 100644 index 0000000000..cf6c30409c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2352/mapper/TheModelsMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2352.mapper; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2352.dto.TheDto; +import org.mapstruct.ap.test.bugs._2352.dto.TheModels; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = TheModelMapper.class) +public interface TheModelsMapper { + + TheModelsMapper INSTANCE = Mappers.getMapper( TheModelsMapper.class ); + + List convert(TheModels theModels); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2356/Issue2356Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2356/Issue2356Mapper.java new file mode 100644 index 0000000000..173645d118 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2356/Issue2356Mapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2356; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2356Mapper { + + Issue2356Mapper INSTANCE = Mappers.getMapper( Issue2356Mapper.class ); + + class Car { + //CHECKSTYLE:OFF + public String brand; + public String model; + public String modelInternational; + //CHECKSTYLE:ON + } + + class CarDTO { + //CHECKSTYLE:OFF + public String brand; + public String modelName; + //CHECKSTYLE:ON + } + + // When using InheritInverseConfiguration the mapping from in to modelName should be ignored + // and shouldn't lead to a compile error. + @Mapping(target = "modelName", source = "in") + CarDTO map(Car in); + + default String mapToModel(Car in) { + return in.modelInternational == null ? in.model : in.modelInternational; + } + + @InheritInverseConfiguration + @Mapping(target = "model", source = "modelName") + @Mapping(target = "modelInternational", ignore = true) + Car map(CarDTO in); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2356/Issue2356Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2356/Issue2356Test.java new file mode 100644 index 0000000000..8efc38abd2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2356/Issue2356Test.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2356; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2356") +@WithClasses({ + Issue2356Mapper.class +}) +public class Issue2356Test { + + @ProcessorTest + public void shouldCompile() { + Issue2356Mapper.Car car = new Issue2356Mapper.Car(); + car.brand = "Tesla"; + car.model = "X"; + car.modelInternational = "3"; + Issue2356Mapper.CarDTO dto = Issue2356Mapper.INSTANCE.map( car ); + + assertThat( dto ).isNotNull(); + assertThat( dto.brand ).isEqualTo( "Tesla" ); + assertThat( dto.modelName ).isEqualTo( "3" ); + + car = Issue2356Mapper.INSTANCE.map( dto ); + + assertThat( car ).isNotNull(); + assertThat( car.brand ).isEqualTo( "Tesla" ); + assertThat( car.model ).isEqualTo( "3" ); + assertThat( car.modelInternational ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Address.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Address.java new file mode 100644 index 0000000000..8651165d82 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Address.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2393; + +/** + * @author Filip Hrisafov + */ +public class Address { + + private final String city; + private final Country country; + + public Address(String city, Country country) { + this.city = city; + this.country = country; + } + + public String getCity() { + return city; + } + + public Country getCountry() { + return country; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/AddressDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/AddressDto.java new file mode 100644 index 0000000000..41f771f319 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/AddressDto.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2393; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +public class AddressDto { + + private String city; + private CountryDto country; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public CountryDto getCountry() { + return country; + } + + public void setCountry(CountryDto country) { + this.country = country; + } + + @Mapper(uses = CountryDto.Converter.class) + public interface Converter { + + Converter INSTANCE = Mappers.getMapper( Converter.class ); + + AddressDto convert(Address address); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Country.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Country.java new file mode 100644 index 0000000000..efeaad6fc0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Country.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2393; + +/** + * @author Filip Hrisafov + */ +public class Country { + + private final String name; + + public Country(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/CountryDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/CountryDto.java new file mode 100644 index 0000000000..7e3751efb3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/CountryDto.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2393; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +/** + * @author Filip Hrisafov + */ +public class CountryDto { + + private String name; + private String code; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + @Mapper + public interface Converter { + + @Mapping(target = "code", constant = "UNKNOWN") + CountryDto convert(Country from); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Issue2393Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Issue2393Test.java new file mode 100644 index 0000000000..8595d4c7f1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2393/Issue2393Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2393; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2393") +@WithClasses({ + Address.class, + AddressDto.class, + Country.class, + CountryDto.class, +}) +public class Issue2393Test { + + @ProcessorTest + public void shouldUseCorrectImport() { + AddressDto dto = AddressDto.Converter.INSTANCE.convert( new Address( + "Zurich", + new Country( "Switzerland" ) + ) ); + + assertThat( dto.getCity() ).isEqualTo( "Zurich" ); + assertThat( dto.getCountry().getName() ).isEqualTo( "Switzerland" ); + assertThat( dto.getCountry().getCode() ).isEqualTo( "UNKNOWN" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/Issue2437Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/Issue2437Test.java new file mode 100644 index 0000000000..343b8fbf1f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/Issue2437Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2437") +@WithClasses({ + Phone.class, + PhoneDto.class, + PhoneMapper.class, + PhoneParent1Mapper.class, + PhoneParent2Mapper.class, + PhoneSuperMapper.class, +}) +class Issue2437Test { + + @ProcessorTest + void shouldGenerateValidCode() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/Phone.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/Phone.java new file mode 100644 index 0000000000..98027861fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/Phone.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +/** + * @author Filip Hrisafov + */ +public class Phone { + + private final String number; + + public Phone(String number) { + this.number = number; + } + + public String getNumber() { + return number; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneDto.java new file mode 100644 index 0000000000..883e086e89 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +/** + * @author Filip Hrisafov + */ +public class PhoneDto { + + private final String number; + + public PhoneDto(String number) { + this.number = number; + } + + public String getNumber() { + return number; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneMapper.java new file mode 100644 index 0000000000..16b01658be --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface PhoneMapper extends PhoneParent1Mapper, PhoneParent2Mapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneParent1Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneParent1Mapper.java new file mode 100644 index 0000000000..0b4da27c15 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneParent1Mapper.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +/** + * @author Filip Hrisafov + */ +public interface PhoneParent1Mapper extends PhoneSuperMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneParent2Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneParent2Mapper.java new file mode 100644 index 0000000000..77e9db6235 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneParent2Mapper.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +/** + * @author Filip Hrisafov + */ +public interface PhoneParent2Mapper extends PhoneSuperMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneSuperMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneSuperMapper.java new file mode 100644 index 0000000000..ba35b21d9b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2437/PhoneSuperMapper.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2437; + +/** + * @author Filip Hrisafov + */ +public interface PhoneSuperMapper { + + Phone map(PhoneDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2439/ErroneousIssue2439Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2439/ErroneousIssue2439Mapper.java new file mode 100644 index 0000000000..a154d55fff --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2439/ErroneousIssue2439Mapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2439; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousIssue2439Mapper { + + @Mapping(target = "modeName", source = "mode.desc") + LiveDto map(LiveEntity entity); + + class LiveEntity { + private final LiveMode[] mode; + + public LiveEntity(LiveMode... mode) { + this.mode = mode; + } + + public LiveMode[] getMode() { + return mode; + } + } + + class LiveDto { + private String modeName; + + public String getModeName() { + return modeName; + } + + public void setModeName(String modeName) { + this.modeName = modeName; + } + } + + enum LiveMode { + TEST, + PROD, + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2439/Issuer2439Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2439/Issuer2439Test.java new file mode 100644 index 0000000000..c3c4702927 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2439/Issuer2439Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2439; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2439") +@WithClasses({ + ErroneousIssue2439Mapper.class +}) +class Issuer2439Test { + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousIssue2439Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "No property named \"mode.desc\" exists in source parameter(s)." + + " Type \"ErroneousIssue2439Mapper.LiveMode[]\" has no properties.") + } + ) + void shouldProvideGoodErrorMessage() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2478/Issue2478Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2478/Issue2478Mapper.java new file mode 100644 index 0000000000..3cec3e0b3c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2478/Issue2478Mapper.java @@ -0,0 +1,86 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2478; + +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2478Mapper { + + Issue2478Mapper INSTANCE = Mappers.getMapper( Issue2478Mapper.class ); + + ProductEntity productFromDto(Product dto, @Context Shop shop); + + class Product { + protected final String name; + protected final Shop shop; + + public Product(String name, Shop shop) { + this.name = name; + this.shop = shop; + } + + public String getName() { + return name; + } + + public Shop getShop() { + return shop; + } + } + + class Shop { + protected final String name; + + public Shop(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class ProductEntity { + + protected String name; + protected ShopEntity shop; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ShopEntity getShop() { + return shop; + } + + public void setShop(ShopEntity shop) { + this.shop = shop; + } + } + + class ShopEntity { + protected String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2478/Issue2478Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2478/Issue2478Test.java new file mode 100644 index 0000000000..05e21f4c40 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2478/Issue2478Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2478; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2478") +@WithClasses({ + Issue2478Mapper.class +}) +class Issue2478Test { + + @ProcessorTest + void shouldGenerateCodeThatCompiles() { + Issue2478Mapper.Product dto = new Issue2478Mapper.Product( "Test", new Issue2478Mapper.Shop( "Shopify" ) ); + Issue2478Mapper.ProductEntity entity = Issue2478Mapper.INSTANCE.productFromDto( dto, dto.getShop() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.getName() ).isEqualTo( "Test" ); + assertThat( entity.getShop() ).isNotNull(); + assertThat( entity.getShop().getName() ).isEqualTo( "Shopify" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2501/Issue2501Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2501/Issue2501Mapper.java new file mode 100644 index 0000000000..08fa637791 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2501/Issue2501Mapper.java @@ -0,0 +1,62 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2501; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2501Mapper { + + Issue2501Mapper INSTANCE = Mappers.getMapper( Issue2501Mapper.class ); + + Customer map(CustomerDTO value); + + CustomerStatus map(DtoStatus status); + + default T unwrap(Optional optional) { + return optional.orElse( null ); + } + + enum CustomerStatus { + ENABLED, DISABLED, + } + + class Customer { + + private CustomerStatus status; + + public CustomerStatus getStatus() { + return status; + } + + public void setStatus(CustomerStatus stat) { + this.status = stat; + } + } + + enum DtoStatus { + ENABLED, DISABLED + } + + class CustomerDTO { + + private DtoStatus status; + + public Optional getStatus() { + return Optional.ofNullable( status ); + } + + public void setStatus(DtoStatus stat) { + this.status = stat; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2501/Issue2501Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2501/Issue2501Test.java new file mode 100644 index 0000000000..c5eb1e0aed --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2501/Issue2501Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2501; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue2501Mapper.class +}) +class Issue2501Test { + + @ProcessorTest + void shouldUnwrapEnumOptional() { + Issue2501Mapper.CustomerDTO source = new Issue2501Mapper.CustomerDTO(); + source.setStatus( Issue2501Mapper.DtoStatus.DISABLED ); + + Issue2501Mapper.Customer target = Issue2501Mapper.INSTANCE.map( source ); + + assertThat( target.getStatus() ).isEqualTo( Issue2501Mapper.CustomerStatus.DISABLED ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2505/Issue2505Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2505/Issue2505Mapper.java new file mode 100644 index 0000000000..525eb09fd3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2505/Issue2505Mapper.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2505; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( mappingControl = DeepClone.class ) +public interface Issue2505Mapper { + + Issue2505Mapper INSTANCE = Mappers.getMapper( Issue2505Mapper.class ); + + Customer map(CustomerDTO value); + + enum Status { + ENABLED, DISABLED, + } + + class Customer { + + private Status status; + + public Status getStatus() { + return status; + } + + public void setStatus(Status stat) { + this.status = stat; + } + } + + class CustomerDTO { + + private Status status; + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2505/Issue2505Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2505/Issue2505Test.java new file mode 100644 index 0000000000..b3fa6ea3c1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2505/Issue2505Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2505; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak derksen + */ +@IssueKey("2505") +@WithClasses( Issue2505Mapper.class ) +class Issue2505Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( Issue2505Mapper.class ); + + @ProcessorTest + void shouldNotGenerateEnumMappingMethodForDeepClone() { + Issue2505Mapper.CustomerDTO source = new Issue2505Mapper.CustomerDTO(); + source.setStatus( Issue2505Mapper.Status.DISABLED ); + + Issue2505Mapper.Customer target = Issue2505Mapper.INSTANCE.map( source ); + + assertThat( target.getStatus() ).isEqualTo( Issue2505Mapper.Status.DISABLED ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2530/Issue2530Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2530/Issue2530Mapper.java new file mode 100644 index 0000000000..268237376c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2530/Issue2530Mapper.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2530; + +import java.time.LocalDate; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Issue2530Mapper { + + Issue2530Mapper INSTANCE = Mappers.getMapper( Issue2530Mapper.class ); + + @Mapping(target = "date", source = ".", dateFormat = "yyyy-MM-dd") + Test map(String s); + + class Test { + + LocalDate date; + + public LocalDate getDate() { + return date; + } + + public void setDate(LocalDate dateTime) { + this.date = dateTime; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2530/Issue2530Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2530/Issue2530Test.java new file mode 100644 index 0000000000..2999939a78 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2530/Issue2530Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2530; + +import java.time.Month; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Ben Zegveld + */ +@IssueKey("2530") +@WithClasses({ + Issue2530Mapper.class +}) +public class Issue2530Test { + + @ProcessorTest + public void shouldConvert() { + Issue2530Mapper.Test target = Issue2530Mapper.INSTANCE.map( "2021-07-31" ); + + assertThat( target ).isNotNull(); + assertThat( target.getDate().getYear() ).isEqualTo( 2021 ); + assertThat( target.getDate().getMonth() ).isEqualTo( Month.JULY ); + assertThat( target.getDate().getDayOfMonth() ).isEqualTo( 31 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2537/ImplicitSourceTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2537/ImplicitSourceTest.java new file mode 100644 index 0000000000..edcbbfd4d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2537/ImplicitSourceTest.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2537; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * implicit source-target mapping should list the source property as being mapped. + * + * @author Ben Zegveld + */ +@WithClasses( { UnmappedSourcePolicyWithImplicitSourceMapper.class } ) +@IssueKey( "2537" ) +public class ImplicitSourceTest { + + @ProcessorTest + public void situationCompilesWithoutErrors() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2537/UnmappedSourcePolicyWithImplicitSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2537/UnmappedSourcePolicyWithImplicitSourceMapper.java new file mode 100644 index 0000000000..21d8ca5332 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2537/UnmappedSourcePolicyWithImplicitSourceMapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2537; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +/** + * @author Ben Zegveld + */ +@Mapper( unmappedSourcePolicy = ReportingPolicy.ERROR ) +public interface UnmappedSourcePolicyWithImplicitSourceMapper { + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "property" ) + Target map(Source source); + + class Source { + private String property; + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + } + + class Target { + private String property; + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/Group.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/Group.java new file mode 100644 index 0000000000..4451431fee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/Group.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2538; + +/** + * @author Filip Hrisafov + */ +public class Group { + + private final String id; + + public Group(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/GroupDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/GroupDto.java new file mode 100644 index 0000000000..0d94c90815 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/GroupDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2538; + +/** + * @author Filip Hrisafov + */ +public class GroupDto { + + private final String id; + + public GroupDto(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/Issue2538Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/Issue2538Test.java new file mode 100644 index 0000000000..cf99e67f92 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/Issue2538Test.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2538; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Group.class, + GroupDto.class, + TeamMapper.class, + TeamRole.class, + TeamRoleDto.class, +}) +class Issue2538Test { + + @ProcessorTest + void shouldCorrectlyUseQualifiedMethodIn2StepMapping() { + TeamRole role = TeamMapper.INSTANCE.mapUsingFirstLookup( new TeamRoleDto( "test" ) ); + + assertThat( role ).isNotNull(); + assertThat( role.getGroup() ).isNotNull(); + assertThat( role.getGroup().getId() ).isEqualTo( "lookup-test" ); + + role = TeamMapper.INSTANCE.mapUsingSecondLookup( new TeamRoleDto( "test" ) ); + + assertThat( role ).isNotNull(); + assertThat( role.getGroup() ).isNotNull(); + assertThat( role.getGroup().getId() ).isEqualTo( "second-test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamMapper.java new file mode 100644 index 0000000000..5615e7bc43 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamMapper.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2538; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface TeamMapper { + + TeamMapper INSTANCE = Mappers.getMapper( TeamMapper.class ); + + // This method is testing methodX(methodY(...)) where methodY is qualified + @Mapping(target = "group", source = "groupId", qualifiedByName = "firstLookup") + TeamRole mapUsingFirstLookup(TeamRoleDto in); + + // This method is testing methodX(methodY(...)) where methodX is qualified + @Mapping(target = "group", source = "groupId", qualifiedByName = "secondLookup") + TeamRole mapUsingSecondLookup(TeamRoleDto in); + + Group map(GroupDto in); + + @Named("firstLookup") + default GroupDto lookupGroup(String groupId) { + return groupId != null ? new GroupDto( "lookup-" + groupId ) : null; + } + + default GroupDto normalLookup(String groupId) { + return groupId != null ? new GroupDto( groupId ) : null; + } + + @Named("secondLookup") + default Group mapSecondLookup(GroupDto in) { + return in != null ? new Group( "second-" + in.getId() ) : null; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamRole.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamRole.java new file mode 100644 index 0000000000..f73700fa4d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamRole.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2538; + +/** + * @author Filip Hrisafov + */ +public class TeamRole { + + private final Group group; + + public TeamRole(Group group) { + this.group = group; + } + + public Group getGroup() { + return group; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamRoleDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamRoleDto.java new file mode 100644 index 0000000000..fac5a1a9ee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2538/TeamRoleDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2538; + +/** + * @author Filip Hrisafov + */ +public class TeamRoleDto { + + private final String groupId; + + public TeamRoleDto(String groupId) { + this.groupId = groupId; + } + + public String getGroupId() { + return groupId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Issue2541Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Issue2541Mapper.java new file mode 100644 index 0000000000..0531f5242c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Issue2541Mapper.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2541; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2541Mapper { + + Issue2541Mapper INSTANCE = Mappers.getMapper( Issue2541Mapper.class ); + + Target map(Source source); + + default Optional toOptional(@Nullable T value) { + return Optional.ofNullable( value ); + } + + class Target { + private Optional value; + + public Optional getValue() { + return value; + } + + public void setValue(Optional value) { + this.value = value; + } + } + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Issue2541Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Issue2541Test.java new file mode 100644 index 0000000000..d1b8bd7f52 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Issue2541Test.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2541; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue2541Mapper.class, + Nullable.class, +}) +class Issue2541Test { + + @ProcessorTest + void shouldGenerateCorrectCode() { + Issue2541Mapper.Target target = Issue2541Mapper.INSTANCE.map( new Issue2541Mapper.Source( null ) ); + + assertThat( target.getValue() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Nullable.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Nullable.java new file mode 100644 index 0000000000..24c52eb906 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2541/Nullable.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2541; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ + ElementType.METHOD, + ElementType.TYPE_USE +}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface Nullable { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2544/Issue2544Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2544/Issue2544Mapper.java new file mode 100644 index 0000000000..6d02d709a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2544/Issue2544Mapper.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2544; + +import java.math.BigDecimal; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Issue2544Mapper { + + Issue2544Mapper INSTANCE = Mappers.getMapper( Issue2544Mapper.class ); + + @Mapping( target = "bigNumber", source = ".", numberFormat = "##0.#####E0" ) + Target map(String s); + + class Target { + + private BigDecimal bigNumber; + + public BigDecimal getBigNumber() { + return bigNumber; + } + + public void setBigNumber(BigDecimal bigNumber) { + this.bigNumber = bigNumber; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2544/Issue2544Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2544/Issue2544Test.java new file mode 100644 index 0000000000..4f58f81d08 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2544/Issue2544Test.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2544; + +import java.math.BigDecimal; + +import org.junitpioneer.jupiter.DefaultLocale; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Ben Zegveld + */ +@IssueKey( "2544" ) +@WithClasses( { Issue2544Mapper.class } ) +public class Issue2544Test { + // Parsing numbers is sensitive to locale settings (e.g. decimal point) + + @ProcessorTest + @DefaultLocale("en") + public void shouldConvertEn() { + Issue2544Mapper.Target target = Issue2544Mapper.INSTANCE.map( "123.45679E6" ); + + assertThat( target ).isNotNull(); + assertThat( target.getBigNumber() ).isEqualTo( new BigDecimal( "1.2345679E+8" ) ); + } + + @ProcessorTest + @DefaultLocale("de") + public void shouldConvertDe() { + Issue2544Mapper.Target target = Issue2544Mapper.INSTANCE.map( "123,45679E6" ); + + assertThat( target ).isNotNull(); + assertThat( target.getBigNumber() ).isEqualTo( new BigDecimal( "1.2345679E+8" ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2624/Issue2624Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2624/Issue2624Mapper.java new file mode 100644 index 0000000000..f4d3c3d22d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2624/Issue2624Mapper.java @@ -0,0 +1,76 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2624; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2624Mapper { + + Issue2624Mapper INSTANCE = Mappers.getMapper( Issue2624Mapper.class ); + + @Mapping( target = "department.id", source = "did") + @Mapping( target = "department.name", source = "dname") + Employee fromMap(Map source); + + class Employee { + private String id; + private String name; + private Department department; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Department getDepartment() { + return department; + } + + public void setDepartment(Department department) { + this.department = department; + } + } + + class Department { + private String id; + private String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2624/Issue2624Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2624/Issue2624Test.java new file mode 100644 index 0000000000..2fb04ef3a0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2624/Issue2624Test.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2624; + +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue2624Mapper.class +}) +class Issue2624Test { + + @ProcessorTest + void shouldCorrectlyMapNestedTargetFromMap() { + Map map = new HashMap<>(); + map.put( "id", "1234" ); + map.put( "name", "Tester" ); + map.put( "did", "4321" ); //Department Id + map.put( "dname", "Test" ); // Department name + + Issue2624Mapper.Employee employee = Issue2624Mapper.INSTANCE.fromMap( map ); + + assertThat( employee ).isNotNull(); + assertThat( employee.getId() ).isEqualTo( "1234" ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + Issue2624Mapper.Department department = employee.getDepartment(); + assertThat( department ).isNotNull(); + assertThat( department.getId() ).isEqualTo( "4321" ); + assertThat( department.getName() ).isEqualTo( "Test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Issue2663Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Issue2663Mapper.java new file mode 100644 index 0000000000..0ac236372a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Issue2663Mapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper( uses = NullableHelper.class ) +public interface Issue2663Mapper { + + Issue2663Mapper INSTANCE = Mappers.getMapper( Issue2663Mapper.class ); + + Request map(RequestDto dto); + + default JsonNullable mapJsonNullableChildren(JsonNullable dtos) { + if ( dtos.isPresent() ) { + return JsonNullable.of( mapChild( dtos.get() ) ); + } + else { + return JsonNullable.undefined(); + } + } + + Request.ChildRequest mapChild(RequestDto.ChildRequestDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Issue2663Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Issue2663Test.java new file mode 100644 index 0000000000..efd14b1d36 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Issue2663Test.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey( "2663" ) +@WithClasses({ + Issue2663Mapper.class, + JsonNullable.class, + Nullable.class, + NullableHelper.class, + Request.class, + RequestDto.class +}) +public class Issue2663Test { + + @ProcessorTest + public void shouldUnpackGenericsCorrectly() { + RequestDto dto = new RequestDto(); + dto.setName( JsonNullable.of( "Tester" ) ); + + Request request = Issue2663Mapper.INSTANCE.map( dto ); + + assertThat( request.getName() ) + .extracting( Nullable::get ) + .isEqualTo( "Tester" ); + + dto.setName( JsonNullable.undefined() ); + + request = Issue2663Mapper.INSTANCE.map( dto ); + + assertThat( request.getName() ) + .extracting( Nullable::isPresent ) + .isEqualTo( false ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/JsonNullable.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/JsonNullable.java new file mode 100644 index 0000000000..0c1aeaba93 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/JsonNullable.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +import java.util.NoSuchElementException; + +/** + * @author Filip Hrisafov + */ +public class JsonNullable { + + private static final JsonNullable UNDEFINED = new JsonNullable<>( null, false ); + + private final T value; + private final boolean present; + + private JsonNullable(T value, boolean present) { + this.value = value; + this.present = present; + } + + public T get() { + if ( !present ) { + throw new NoSuchElementException("Value is undefined"); + } + return value; + } + + public boolean isPresent() { + return present; + } + + @SuppressWarnings("unchecked") + public static JsonNullable undefined() { + return (JsonNullable) UNDEFINED; + } + + public static JsonNullable of(T value) { + return new JsonNullable<>( value, true ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Nullable.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Nullable.java new file mode 100644 index 0000000000..6701793ed9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Nullable.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +import java.util.NoSuchElementException; + +/** + * @author Filip Hrisafov + */ +public class Nullable { + + @SuppressWarnings("rawtypes") + private static final Nullable UNDEFINED = new Nullable<>( null, false ); + + private final T value; + private final boolean present; + + private Nullable(T value, boolean present) { + this.value = value; + this.present = present; + } + + public T get() { + if ( !present ) { + throw new NoSuchElementException("Value is undefined"); + } + return value; + } + + public boolean isPresent() { + return present; + } + + public static Nullable of(T value) { + return new Nullable<>( value, true ); + } + + @SuppressWarnings("unchecked") + public static Nullable undefined() { + return (Nullable) UNDEFINED; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/NullableHelper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/NullableHelper.java new file mode 100644 index 0000000000..ae68300e62 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/NullableHelper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +/** + * @author Filip Hrisafov + */ +public class NullableHelper { + + private NullableHelper() { + // Helper class + } + + public static Nullable jsonNullableToNullable(JsonNullable jsonNullable) { + if ( jsonNullable.isPresent() ) { + return Nullable.of( jsonNullable.get() ); + } + return Nullable.undefined(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Request.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Request.java new file mode 100644 index 0000000000..8b58e2e0b5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/Request.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +/** + * @author Filip Hrisafov + */ +public class Request { + + private Nullable name = Nullable.undefined(); + private Nullable child = Nullable.undefined(); + + public Nullable getName() { + return name; + } + + public void setName(Nullable name) { + this.name = name; + } + + public Nullable getChild() { + return child; + } + + public void setChild(Nullable child) { + this.child = child; + } + + public static class ChildRequest { + + private Nullable name = Nullable.undefined(); + + public Nullable getName() { + return name; + } + + public void setName(Nullable name) { + this.name = name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/RequestDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/RequestDto.java new file mode 100644 index 0000000000..d1a93a9bd4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2663/RequestDto.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2663; + +/** + * @author Filip Hrisafov + */ +public class RequestDto { + + private JsonNullable name = JsonNullable.undefined(); + private JsonNullable child = JsonNullable.undefined(); + + public JsonNullable getName() { + return name; + } + + public void setName(JsonNullable name) { + this.name = name; + } + + public JsonNullable getChild() { + return child; + } + + public void setChild(JsonNullable child) { + this.child = child; + } + + public static class ChildRequestDto { + + private JsonNullable name = JsonNullable.undefined(); + + public JsonNullable getName() { + return name; + } + + public void setName(JsonNullable name) { + this.name = name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Erroneous2668ListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Erroneous2668ListMapper.java new file mode 100644 index 0000000000..beb1d3283a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Erroneous2668ListMapper.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2668; + +import java.util.ArrayList; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Erroneous2668ListMapper { + + Erroneous2668ListMapper INSTANCE = Mappers.getMapper( Erroneous2668ListMapper.class ); + + CollectionTarget map(CollectionSource source); + + class CollectionTarget { + MyArrayList list; + + public MyArrayList getList() { + return list; + } + + public void setList(MyArrayList list) { + this.list = list; + } + } + + class CollectionSource { + MyArrayList list; + + public MyArrayList getList() { + return list; + } + + public void setList(MyArrayList list) { + this.list = list; + } + } + + class MyArrayList extends ArrayList { + private String unusable; + + public MyArrayList(String unusable) { + this.unusable = unusable; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Erroneous2668MapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Erroneous2668MapMapper.java new file mode 100644 index 0000000000..3c9bcd3926 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Erroneous2668MapMapper.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2668; + +import java.util.HashMap; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Erroneous2668MapMapper { + + Erroneous2668MapMapper INSTANCE = Mappers.getMapper( Erroneous2668MapMapper.class ); + + CollectionTarget map(CollectionSource source); + + class CollectionTarget { + MyHashMap map; + + public MyHashMap getMap() { + return map; + } + + public void setMap(MyHashMap map) { + this.map = map; + } + } + + class CollectionSource { + MyHashMap map; + + public MyHashMap getMap() { + return map; + } + + public void setMap(MyHashMap map) { + this.map = map; + } + } + + class MyHashMap extends HashMap { + private String unusable; + + public MyHashMap(String unusable) { + this.unusable = unusable; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Issue2668Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Issue2668Mapper.java new file mode 100644 index 0000000000..1b72e2f636 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Issue2668Mapper.java @@ -0,0 +1,120 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2668; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Issue2668Mapper { + + Issue2668Mapper INSTANCE = Mappers.getMapper( Issue2668Mapper.class ); + + CollectionTarget map(CollectionSource source); + + class CollectionTarget { + MyArrayList list; + MyHashMap map; + MyCopyArrayList copyList; + MyCopyHashMap copyMap; + + public MyArrayList getList() { + return list; + } + + public MyHashMap getMap() { + return map; + } + + public void setList(MyArrayList list) { + this.list = list; + } + + public void setMap(MyHashMap map) { + this.map = map; + } + + public MyCopyArrayList getCopyList() { + return copyList; + } + + public MyCopyHashMap getCopyMap() { + return copyMap; + } + + public void setCopyList(MyCopyArrayList copyList) { + this.copyList = copyList; + } + + public void setCopyMap(MyCopyHashMap copyMap) { + this.copyMap = copyMap; + } + } + + class CollectionSource { + MyArrayList list; + MyHashMap map; + MyCopyArrayList copyList; + MyCopyHashMap copyMap; + + public MyArrayList getList() { + return list; + } + + public MyHashMap getMap() { + return map; + } + + public void setList(MyArrayList list) { + this.list = list; + } + + public void setMap(MyHashMap map) { + this.map = map; + } + + public MyCopyArrayList getCopyList() { + return copyList; + } + + public MyCopyHashMap getCopyMap() { + return copyMap; + } + + public void setCopyList(MyCopyArrayList copyList) { + this.copyList = copyList; + } + + public void setCopyMap(MyCopyHashMap copyMap) { + this.copyMap = copyMap; + } + } + + class MyArrayList extends ArrayList { + } + + class MyHashMap extends HashMap { + } + + class MyCopyArrayList extends ArrayList { + public MyCopyArrayList(Collection copy) { + super( copy ); + } + } + + class MyCopyHashMap extends HashMap { + public MyCopyHashMap(HashMap copy) { + super( copy ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Issue2668Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Issue2668Test.java new file mode 100644 index 0000000000..20b4e445fd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2668/Issue2668Test.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2668; + +import javax.tools.Diagnostic.Kind; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Ben Zegveld + */ +@IssueKey( "2668" ) +class Issue2668Test { + + @ProcessorTest + @WithClasses( Issue2668Mapper.class ) + void shouldCompileCorrectlyWithAvailableConstructors() { + } + + @ProcessorTest + @WithClasses( Erroneous2668ListMapper.class ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = Kind.ERROR, + line = 21, + message = "org.mapstruct.ap.test.bugs._2668.Erroneous2668ListMapper.MyArrayList" + + " does not have an accessible copy or no-args constructor." + ) + } + ) + void errorExpectedBecauseCollectionIsNotUsable() { + } + + @ProcessorTest + @WithClasses( Erroneous2668MapMapper.class ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = Kind.ERROR, + line = 21, + message = "org.mapstruct.ap.test.bugs._2668.Erroneous2668MapMapper.MyHashMap" + + " does not have an accessible copy or no-args constructor." + ) + } + ) + void errorExpectedBecauseMapIsNotUsable() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2673/Issue2673Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2673/Issue2673Mapper.java new file mode 100644 index 0000000000..221197d18f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2673/Issue2673Mapper.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2673; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Issue2673Mapper { + + Issue2673Mapper INSTANCE = Mappers.getMapper( Issue2673Mapper.class ); + + Target map(Source source); + + default T map(Optional opt) { + return opt.orElse( null ); + } + + default Optional map(T t) { + return Optional.ofNullable( t ); + } + + class Target { + private final int primitive; + private final String nonPrimitive; + + public Target(int primitive, String nonPrimitive) { + this.primitive = primitive; + this.nonPrimitive = nonPrimitive; + } + + public int getPrimitive() { + return primitive; + } + + public String getNonPrimitive() { + return nonPrimitive; + } + } + + class Source { + private final int primitive; + private final Optional nonPrimitive; + + public Source(int primitive, Optional nonPrimitive) { + this.primitive = primitive; + this.nonPrimitive = nonPrimitive; + } + + public int getPrimitive() { + return primitive; + } + + public Optional getNonPrimitive() { + return nonPrimitive; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2673/Issue2673Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2673/Issue2673Test.java new file mode 100644 index 0000000000..40a5e79276 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2673/Issue2673Test.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2673; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Ben Zegveld + */ +@WithClasses({ + Issue2673Mapper.class +}) +class Issue2673Test { + + @ProcessorTest + @IssueKey( "2673" ) + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/ErroneousSourceTargetMapping.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/ErroneousSourceTargetMapping.java new file mode 100644 index 0000000000..9157a626b4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/ErroneousSourceTargetMapping.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2674; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +interface ErroneousSourceTargetMapping { + + ErroneousSourceTargetMapping INSTANCE = Mappers.getMapper( ErroneousSourceTargetMapping.class ); + + @BeforeMapping + void beforeMappingMethod(Target target, @MappingTarget Source source); + + @AfterMapping + void afterMappingMethod(Source source, @MappingTarget Target target); + + Target toTarget(Source source); + + Source toSource(Target target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Issue2674Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Issue2674Test.java new file mode 100644 index 0000000000..90530051fa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Issue2674Test.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2674; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static javax.tools.Diagnostic.Kind; + +/** + * @author Justyna Kubica-Ledzion + */ +@IssueKey("2674") +@WithClasses({ Source.class, Target.class, ErroneousSourceTargetMapping.class }) +public class Issue2674Test { + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousSourceTargetMapping.class, + kind = Kind.ERROR, + line = 20, + message = "@BeforeMapping can only be applied to an implemented method."), + @Diagnostic(type = ErroneousSourceTargetMapping.class, + kind = Kind.ERROR, + line = 23, + message = "@AfterMapping can only be applied to an implemented method.") + } + ) + public void shouldRaiseErrorIfThereIsNoAfterOrBeforeMethodImplementation() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Source.java new file mode 100644 index 0000000000..f9145c08b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Source.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2674; + +public class Source { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Target.java new file mode 100644 index 0000000000..244bdeb9a0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2674/Target.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2674; + +public class Target { + + private int id; + private String name; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2677/Issue2677Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2677/Issue2677Mapper.java new file mode 100644 index 0000000000..e74ad1e770 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2677/Issue2677Mapper.java @@ -0,0 +1,117 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2677; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2677Mapper { + + Issue2677Mapper INSTANCE = Mappers.getMapper( Issue2677Mapper.class ); + + @Mapping(target = "id", source = "value.id") + Output map(Wrapper in); + + @Mapping(target = ".", source = "value") + Output mapImplicitly(Wrapper in); + + @Mapping(target = "id", source = "value.id") + Output mapFromParent(Wrapper in); + + @Mapping(target = "id", source = "value.id") + Output mapFromChild(Wrapper in); + + @Mapping( target = "value", source = "wrapperValue") + Wrapper mapToWrapper(String wrapperValue, Wrapper wrapper); + + @Mapping(target = "id", source = "value.id") + Output mapWithPresenceCheck(Wrapper in); + + class Wrapper { + private final T value; + private final String status; + + public Wrapper(T value, String status) { + this.value = value; + this.status = status; + } + + public String getStatus() { + return status; + } + + public T getValue() { + return value; + } + } + + class Parent { + private final int id; + + public Parent(int id) { + this.id = id; + } + + public int getId() { + return id; + } + } + + class Child extends Parent { + private final String whatever; + + public Child(int id, String whatever) { + super( id ); + this.whatever = whatever; + } + + public String getWhatever() { + return whatever; + } + } + + class ParentWithPresenceCheck { + private final int id; + + public ParentWithPresenceCheck(int id) { + this.id = id; + } + + public int getId() { + return id; + } + + public boolean hasId() { + return id > 10; + } + } + + class Output { + private int id; + private String status; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2677/Issue2677Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2677/Issue2677Test.java new file mode 100644 index 0000000000..0eb4d6d794 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2677/Issue2677Test.java @@ -0,0 +1,92 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2677; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2677") +@WithClasses({ + Issue2677Mapper.class +}) +class Issue2677Test { + + @ProcessorTest + void shouldCorrectlyUseGenericsWithExtends() { + Issue2677Mapper.Parent parent = new Issue2677Mapper.Parent( 10 ); + Issue2677Mapper.Child child = new Issue2677Mapper.Child( 15, "Test" ); + + Issue2677Mapper.Output output = Issue2677Mapper.INSTANCE.map( new Issue2677Mapper.Wrapper<>( + parent, + "extends" + ) ); + + assertThat( output.getStatus() ).isEqualTo( "extends" ); + assertThat( output.getId() ).isEqualTo( 10 ); + + output = Issue2677Mapper.INSTANCE.mapFromChild( new Issue2677Mapper.Wrapper<>( + child, + "child" + ) ); + + assertThat( output.getStatus() ).isEqualTo( "child" ); + assertThat( output.getId() ).isEqualTo( 15 ); + + output = Issue2677Mapper.INSTANCE.mapFromParent( new Issue2677Mapper.Wrapper<>( + parent, + "parent" + ) ); + + assertThat( output.getStatus() ).isEqualTo( "parent" ); + assertThat( output.getId() ).isEqualTo( 10 ); + + output = Issue2677Mapper.INSTANCE.mapImplicitly( new Issue2677Mapper.Wrapper<>( + child, + "implicit" + ) ); + + assertThat( output.getStatus() ).isEqualTo( "implicit" ); + assertThat( output.getId() ).isEqualTo( 15 ); + + Issue2677Mapper.Wrapper result = Issue2677Mapper.INSTANCE.mapToWrapper( + "test", + new Issue2677Mapper.Wrapper<>( + child, + "super" + ) + ); + + assertThat( result.getStatus() ).isEqualTo( "super" ); + assertThat( result.getValue() ).isEqualTo( "test" ); + + output = Issue2677Mapper.INSTANCE.mapWithPresenceCheck( + new Issue2677Mapper.Wrapper<>( + new Issue2677Mapper.ParentWithPresenceCheck( 8 ), + "presenceCheck" + ) + ); + + assertThat( output.getStatus() ).isEqualTo( "presenceCheck" ); + assertThat( output.getId() ).isEqualTo( 0 ); + + output = Issue2677Mapper.INSTANCE.mapWithPresenceCheck( + new Issue2677Mapper.Wrapper<>( + new Issue2677Mapper.ParentWithPresenceCheck( 15 ), + "presenceCheck" + ) + ); + + assertThat( output.getStatus() ).isEqualTo( "presenceCheck" ); + assertThat( output.getId() ).isEqualTo( 15 ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/Issue2704Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/Issue2704Test.java new file mode 100644 index 0000000000..5920a6022b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/Issue2704Test.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2704; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Valentin Kulesh + */ +@IssueKey("2704") +@WithClasses({ TestMapper.class, TopLevel.class }) +public class Issue2704Test { + @ProcessorTest + public void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/TestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/TestMapper.java new file mode 100644 index 0000000000..846a783437 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/TestMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2704; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.bugs._2704.TopLevel.Target; + +/** + * @author Valentin Kulesh + */ +@Mapper(implementationPackage = "") +public interface TestMapper { + @Mapping(target = "e", constant = "VALUE1") + Target test(Object unused); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/TopLevel.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/TopLevel.java new file mode 100644 index 0000000000..ef30c2cd6e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2704/TopLevel.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2704; + +/** + * @author Valentin Kulesh + */ +public interface TopLevel { + enum InnerEnum { + VALUE1, + VALUE2, + } + + class Target { + public void setE(@SuppressWarnings("unused") InnerEnum e) { + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2743/Issue2743Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2743/Issue2743Mapper.java new file mode 100644 index 0000000000..db3c0e6d49 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2743/Issue2743Mapper.java @@ -0,0 +1,75 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2743; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface Issue2743Mapper { + + @BeanMapping(ignoreUnmappedSourceProperties = { "number" }) + Target map(Source source); + + class Source { + + private final int number = 10; + private final NestedSource nested; + + public Source(NestedSource nested) { + this.nested = nested; + } + + public int getNumber() { + return number; + } + + public NestedSource getNested() { + return nested; + } + } + + class NestedSource { + private final String value; + + public NestedSource(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + + private final NestedTarget nested; + + public Target(NestedTarget nested) { + this.nested = nested; + } + + public NestedTarget getNested() { + return nested; + } + } + + class NestedTarget { + private final String value; + + public NestedTarget(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2743/Issue2743Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2743/Issue2743Test.java new file mode 100644 index 0000000000..5c2bb61279 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2743/Issue2743Test.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2743; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2743") +@WithClasses({ + Issue2743Mapper.class +}) +class Issue2743Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2748/Issue2748Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2748/Issue2748Mapper.java new file mode 100644 index 0000000000..0062667df4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2748/Issue2748Mapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2748; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2748Mapper { + + Issue2748Mapper INSTANCE = Mappers.getMapper( Issue2748Mapper.class ); + + @Mapping(target = "specificValue", source = "annotations.specific/value") + Target map(Source source); + + class Target { + private final String specificValue; + + public Target(String specificValue) { + this.specificValue = specificValue; + } + + public String getSpecificValue() { + return specificValue; + } + } + + class Source { + private final Map annotations; + + public Source(Map annotations) { + this.annotations = annotations; + } + + public Map getAnnotations() { + return annotations; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2748/Issue2748Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2748/Issue2748Test.java new file mode 100644 index 0000000000..4bda2cd43d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2748/Issue2748Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2748; + +import java.util.Collections; +import java.util.Map; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2748") +@WithClasses( { + Issue2748Mapper.class +} ) +class Issue2748Test { + + @ProcessorTest + void shouldMapNonJavaIdentifier() { + Map annotations = Collections.singletonMap( "specific/value", "value" ); + Issue2748Mapper.Source source = new Issue2748Mapper.Source( annotations ); + + Issue2748Mapper.Target target = Issue2748Mapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getSpecificValue() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2781/Issue2781Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2781/Issue2781Mapper.java new file mode 100644 index 0000000000..9abdf560c4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2781/Issue2781Mapper.java @@ -0,0 +1,53 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2781; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Mengxing Yuan + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface Issue2781Mapper { + + Issue2781Mapper INSTANCE = Mappers.getMapper( Issue2781Mapper.class ); + + @Mapping(target = "nested", source = "source") + Target map(Source source); + + class Target { + private Source nested; + + public Source getNested() { + return nested; + } + + public void setNested(Source nested) { + this.nested = nested; + } + } + + class Source { + private String field1; + private String field2; + + public Source(String field1, String field2) { + this.field1 = field1; + this.field2 = field2; + } + + public String getField1() { + return field1; + } + + public String getField2() { + return field2; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2781/Issue2781Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2781/Issue2781Test.java new file mode 100644 index 0000000000..80ac4f5ce3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2781/Issue2781Test.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2781; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Mengxing Yuan + */ +@IssueKey("2781") +@WithClasses({ + Issue2781Mapper.class +}) +class Issue2781Test { + + @ProcessorTest + void shouldCompileWithoutErrors() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Issue2795Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Issue2795Mapper.java new file mode 100644 index 0000000000..41f29da920 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Issue2795Mapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2795; + +import java.util.Optional; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; + +@Mapper +public interface Issue2795Mapper { + + void update(Source update, @MappingTarget Target destination); + + void update(NestedDto update, @MappingTarget Nested destination); + + static T unwrap(Optional optional) { + return optional.orElse( null ); + } + + @Condition + static boolean isNotEmpty(Optional field) { + return field != null && field.isPresent(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Issue2795Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Issue2795Test.java new file mode 100644 index 0000000000..4b7b599527 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Issue2795Test.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2795; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@IssueKey("2795") +@WithClasses({ + Issue2795Mapper.class, + Nested.class, + NestedDto.class, + Target.class, + Source.class, +}) +public class Issue2795Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Nested.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Nested.java new file mode 100644 index 0000000000..5214c7d076 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Nested.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2795; + +public class Nested { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/NestedDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/NestedDto.java new file mode 100644 index 0000000000..1b27453435 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/NestedDto.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2795; + +public class NestedDto { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Source.java new file mode 100644 index 0000000000..927e2b09f5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2795; + +import java.util.Optional; + +public class Source { + + private Optional nested = Optional.empty(); + + public Optional getNested() { + return nested; + } + + public void setNested(Optional nested) { + this.nested = nested; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Target.java new file mode 100644 index 0000000000..ed69a6d48f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2795/Target.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2795; + +public class Target { + + private Nested nested; + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/ExampleDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/ExampleDto.java new file mode 100644 index 0000000000..eff9f26271 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/ExampleDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2797; + +/** + * @author Ben Zegveld + */ +public class ExampleDto { + + private String personFirstName; + private String personLastName; + + public String getPersonFirstName() { + return personFirstName; + } + + public String getPersonLastName() { + return personLastName; + } + + public void setPersonFirstName(String personFirstName) { + this.personFirstName = personFirstName; + } + + public void setPersonLastName(String personLastName) { + this.personLastName = personLastName; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/ExampleMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/ExampleMapper.java new file mode 100644 index 0000000000..eccac27256 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/ExampleMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2797; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.bugs._2797.model.Example.Person; + +import static org.mapstruct.ReportingPolicy.ERROR; + +/** + * @author Ben Zegveld + */ +@Mapper(unmappedTargetPolicy = ERROR) +public interface ExampleMapper { + + @Mapping(target = "personFirstName", source = "names.first") + @Mapping(target = "personLastName", source = "names.last") + ExampleDto map(Person person); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/Issue2797Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/Issue2797Test.java new file mode 100644 index 0000000000..7f3dd5f3de --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/Issue2797Test.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2797; + +import org.mapstruct.ap.test.bugs._2797.model.BasePerson; +import org.mapstruct.ap.test.bugs._2797.model.Example; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Ben Zegveld + */ +@IssueKey( "2797" ) +@WithClasses( { ExampleDto.class, ExampleMapper.class, Example.class, BasePerson.class } ) +public class Issue2797Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/model/BasePerson.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/model/BasePerson.java new file mode 100644 index 0000000000..6b54e6ee31 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/model/BasePerson.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2797.model; + +/** + * @author Ben Zegveld + */ +public class BasePerson { + + private Names names; + + public Names getNames() { + return names; + } + + public void setNames(Names names) { + this.names = names; + } + + public static class Names { + + private String first; + private String last; + + public String getFirst() { + return first; + } + + public String getLast() { + return last; + } + + public void setFirst(String first) { + this.first = first; + } + + public void setLast(String last) { + this.last = last; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/model/Example.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/model/Example.java new file mode 100644 index 0000000000..4dfa40f695 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2797/model/Example.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2797.model; + +/** + * @author Ben Zegveld + */ +public class Example { + + public static class Person extends BasePerson { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/Issue2807Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/Issue2807Test.java new file mode 100644 index 0000000000..102a9d26eb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/Issue2807Test.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2807.spring; + +import org.mapstruct.ap.test.bugs._2807.spring.after.AfterMethod; +import org.mapstruct.ap.test.bugs._2807.spring.before.BeforeMethod; +import org.mapstruct.ap.test.bugs._2807.spring.beforewithtarget.BeforeWithTarget; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; + +/** + * @author Ben Zegveld + */ +@IssueKey( "2807" ) +public class Issue2807Test { + + @ProcessorTest + @WithSpring + @WithClasses( { SpringLifeCycleMapper.class, BeforeMethod.class, BeforeWithTarget.class, AfterMethod.class } ) + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/SpringLifeCycleMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/SpringLifeCycleMapper.java new file mode 100644 index 0000000000..408a2ca3e0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/SpringLifeCycleMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2807.spring; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.bugs._2807.spring.after.AfterMethod; +import org.mapstruct.ap.test.bugs._2807.spring.before.BeforeMethod; +import org.mapstruct.ap.test.bugs._2807.spring.beforewithtarget.BeforeWithTarget; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper( componentModel = "spring", uses = { BeforeMethod.class, AfterMethod.class, + BeforeWithTarget.class }, unmappedTargetPolicy = ReportingPolicy.IGNORE ) +public interface SpringLifeCycleMapper { + SpringLifeCycleMapper INSTANCE = Mappers.getMapper( SpringLifeCycleMapper.class ); + + List map(List list); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/after/AfterMethod.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/after/AfterMethod.java new file mode 100644 index 0000000000..05770c6603 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/after/AfterMethod.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2807.spring.after; + +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.MappingTarget; + +/** + * @author Ben Zegveld + */ +public class AfterMethod { + private AfterMethod() { + } + + @AfterMapping + public static void doNothing(@MappingTarget List source) { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/before/BeforeMethod.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/before/BeforeMethod.java new file mode 100644 index 0000000000..9fb9e7e883 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/before/BeforeMethod.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2807.spring.before; + +import org.mapstruct.BeforeMapping; + +/** + * @author Ben Zegveld + */ +public class BeforeMethod { + private BeforeMethod() { + } + + @BeforeMapping + public static void doNothing(Iterable source) { + return; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/beforewithtarget/BeforeWithTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/beforewithtarget/BeforeWithTarget.java new file mode 100644 index 0000000000..a3ee8b57ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2807/spring/beforewithtarget/BeforeWithTarget.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2807.spring.beforewithtarget; + +import java.util.List; + +import org.mapstruct.BeforeMapping; +import org.mapstruct.MappingTarget; + +/** + * @author Ben Zegveld + */ +public class BeforeWithTarget { + private BeforeWithTarget() { + } + + @BeforeMapping + public static void doNothingBeforeWithTarget(Iterable source, @MappingTarget List target) { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Animal.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Animal.java new file mode 100644 index 0000000000..3d60eac9fa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Animal.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2825; + +/** + * @author orange add + */ +public class Animal { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Cat.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Cat.java new file mode 100644 index 0000000000..ec826c0ffb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Cat.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2825; + +/** + * @author orange add + */ +public class Cat extends Animal { + private String race; + + public String getRace() { + return race; + } + + public void setRace(String race) { + this.race = race; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Dog.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Dog.java new file mode 100644 index 0000000000..53b41a98c9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Dog.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2825; + +/** + * @author orange add + */ +public class Dog extends Animal { + private String race; + + public String getRace() { + return race; + } + + public void setRace(String race) { + this.race = race; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Issue2825Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Issue2825Mapper.java new file mode 100644 index 0000000000..c515011b0b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Issue2825Mapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2825; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.SubclassMapping; +import org.mapstruct.factory.Mappers; + +/** + * @author orange add + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface Issue2825Mapper { + + Issue2825Mapper INSTANCE = Mappers.getMapper( Issue2825Mapper.class ); + + @SubclassMapping(target = TargetAnimal.class, source = Dog.class) + @SubclassMapping(target = TargetAnimal.class, source = Cat.class) + TargetAnimal map(Animal source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Issue2825Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Issue2825Test.java new file mode 100644 index 0000000000..9c0609b754 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/Issue2825Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2825; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author orange add + */ +@IssueKey("2825") +@WithClasses({ + Animal.class, + Cat.class, + Dog.class, + Issue2825Mapper.class, + TargetAnimal.class, +}) +public class Issue2825Test { + + @ProcessorTest + public void mappingMethodShouldNotBeReusedForSubclassMappings() { + Dog dog = new Dog(); + dog.setName( "Lucky" ); + dog.setRace( "Shepherd" ); + TargetAnimal target = Issue2825Mapper.INSTANCE.map( dog ); + assertThat( target.getName() ).isEqualTo( "Lucky" ); + assertThat( target.getRace() ).isEqualTo( "Shepherd" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/TargetAnimal.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/TargetAnimal.java new file mode 100644 index 0000000000..479741099a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2825/TargetAnimal.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2825; + +/** + * @author orange add + */ +public class TargetAnimal { + private String name; + + private String race; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRace() { + return race; + } + + public void setRace(String race) { + this.race = race; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Car.java new file mode 100644 index 0000000000..9419223a42 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Car.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2839; + +import java.util.List; + +/** + * @author Hakan Özkan + */ +public final class Car { + + private final Id id; + private final List seatIds; + private final List tireIds; + + public Car(Id id, List seatIds, List tireIds) { + this.id = id; + this.seatIds = seatIds; + this.tireIds = tireIds; + } + + public Id getId() { + return id; + } + + public List getSeatIds() { + return seatIds; + } + + public List getTireIds() { + return tireIds; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/CarDto.java new file mode 100644 index 0000000000..68741ebc92 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/CarDto.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2839; + +import java.util.List; + +/** + * @author Hakan Özkan + */ +public final class CarDto { + + private final String id; + private final List seatIds; + private final List tireIds; + + public CarDto(String id, List seatIds, List tireIds) { + this.id = id; + this.seatIds = seatIds; + this.tireIds = tireIds; + } + + public String getId() { + return id; + } + + public List getSeatIds() { + return seatIds; + } + + public List getTireIds() { + return tireIds; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/CarMapper.java new file mode 100644 index 0000000000..e535935d21 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/CarMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2839; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Hakan Özkan + */ +@Mapper +public abstract class CarMapper { + + public static final CarMapper MAPPER = Mappers.getMapper( CarMapper.class ); + + public abstract Car toEntity(CarDto dto); + + protected Id mapId(String id) throws Issue2839Exception { + throw new Issue2839Exception("For id " + id); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Id.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Id.java new file mode 100644 index 0000000000..5bb9a29dd7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Id.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2839; + +import java.util.UUID; + +/** + * @author Hakan Özkan + */ +public class Id { + + private final UUID id; + + public Id() { + this.id = UUID.randomUUID(); + } + + public Id(UUID id) { + this.id = id; + } + + public UUID getId() { + return id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Issue2839Exception.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Issue2839Exception.java new file mode 100644 index 0000000000..91f02014d6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Issue2839Exception.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2839; + +/** + * @author Hakan Özkan + */ +public class Issue2839Exception extends Exception { + + public Issue2839Exception(String message) { + super( message ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Issue2839Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Issue2839Test.java new file mode 100644 index 0000000000..ed61c39a63 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2839/Issue2839Test.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2839; + +import java.util.Collections; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Hakan Özkan + */ +@IssueKey("2839") +@WithClasses({ + Car.class, + CarDto.class, + CarMapper.class, + Id.class, + Issue2839Exception.class, +}) +public class Issue2839Test { + + @ProcessorTest + void shouldCompile() { + CarDto car1 = new CarDto( + "carId", + Collections.singletonList( "seatId" ), + Collections.singletonList( "tireId" ) + ); + assertThatThrownBy( () -> CarMapper.MAPPER.toEntity( car1 ) ) + .isExactlyInstanceOf( RuntimeException.class ) + .getCause() + .isInstanceOf( Issue2839Exception.class ) + .hasMessage( "For id seatId" ); + + CarDto car2 = new CarDto( "carId", Collections.emptyList(), Collections.singletonList( "tireId" ) ); + assertThatThrownBy( () -> CarMapper.MAPPER.toEntity( car2 ) ) + .isExactlyInstanceOf( RuntimeException.class ) + .getCause() + .isInstanceOf( Issue2839Exception.class ) + .hasMessage( "For id tireId" ); + + CarDto car3 = new CarDto( "carId", Collections.emptyList(), Collections.emptyList() ); + assertThatThrownBy( () -> CarMapper.MAPPER.toEntity( car3 ) ) + .isExactlyInstanceOf( RuntimeException.class ) + .getCause() + .isInstanceOf( Issue2839Exception.class ) + .hasMessage( "For id carId" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2840/Issue2840Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2840/Issue2840Mapper.java new file mode 100644 index 0000000000..d2baac8cac --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2840/Issue2840Mapper.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2840; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2840Mapper { + + Issue2840Mapper INSTANCE = + Mappers.getMapper( Issue2840Mapper.class ); + + Issue2840Mapper.Target map(Short shortValue, Integer intValue); + + default int toInt(Number number) { + return number.intValue() + 5; + } + + default short toShort(Number number) { + return (short) (number.shortValue() + 10); + } + + class Target { + + private int intValue; + private short shortValue; + + public int getIntValue() { + return intValue; + } + + public void setIntValue(int intValue) { + this.intValue = intValue; + } + + public short getShortValue() { + return shortValue; + } + + public void setShortValue(short shortValue) { + this.shortValue = shortValue; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2840/Issue2840Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2840/Issue2840Test.java new file mode 100644 index 0000000000..1c6b19306f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2840/Issue2840Test.java @@ -0,0 +1,31 @@ + +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2840; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2840") +@WithClasses({ + Issue2840Mapper.class, +}) +class Issue2840Test { + + @ProcessorTest + void shouldUseMethodWithMostSpecificReturnType() { + Issue2840Mapper.Target target = Issue2840Mapper.INSTANCE.map( (short) 10, 50 ); + + assertThat( target.getShortValue() ).isEqualTo( (short) 20 ); + assertThat( target.getIntValue() ).isEqualTo( 55 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867BaseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867BaseMapper.java new file mode 100644 index 0000000000..8ebe1aa98d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867BaseMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2867; + +import org.mapstruct.MappingTarget; + +/** + * @author Filip Hrisafov + */ +public interface Issue2867BaseMapper { + + void update(@MappingTarget T target, S source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867Mapper.java new file mode 100644 index 0000000000..77dfda0fc9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867Mapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2867; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2867Mapper extends Issue2867BaseMapper { + + class Target { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + class Source { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867Test.java new file mode 100644 index 0000000000..5f0e7ad763 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2867/Issue2867Test.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2867; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue2867BaseMapper.class, + Issue2867Mapper.class, +}) +@IssueKey("2867") +class Issue2867Test { + + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = @Diagnostic( + type = Issue2867Mapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 14, + message = "Unmapped target property: \"name\"." + + " Occured at 'void update(T target, S source)' in 'Issue2867BaseMapper'." + ) + ) + @ProcessorTest + void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Issue2880Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Issue2880Mapper.java new file mode 100644 index 0000000000..218f6d384b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Issue2880Mapper.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2880; + +import org.mapstruct.Mapper; + +@Mapper +public interface Issue2880Mapper { + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Issue2880Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Issue2880Test.java new file mode 100644 index 0000000000..e3d0f810c8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Issue2880Test.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2880; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@IssueKey("2880") +@WithClasses({ + Issue2880Mapper.class, + Outer.class, + Source.class, + Target.class, + TargetData.class +}) +public class Issue2880Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Outer.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Outer.java new file mode 100644 index 0000000000..90b756137a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Outer.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2880; + +public class Outer { + + public static class SourceData { + + // CHECKSTYLE:OFF + public String value; + // CHECKSTYLE:ON + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Source.java new file mode 100644 index 0000000000..0ab3b81661 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Source.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2880; + +import java.util.List; + +public class Source { + + // CHECKSTYLE:OFF + public Outer.SourceData[] data1; + + public Outer.SourceData[] data2; + + public List data3; + + public List data4; + // CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Target.java new file mode 100644 index 0000000000..28c6b1cca1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/Target.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2880; + +import java.util.List; + +public class Target { + + // CHECKSTYLE:OFF + public TargetData[] data1; + + public List data2; + + public TargetData[] data3; + + public List data4; + // CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/TargetData.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/TargetData.java new file mode 100644 index 0000000000..28cca96601 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2880/TargetData.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2880; + +public class TargetData { + + // CHECKSTYLE:OFF + public String value; + // CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Mapper.java index 95dad2c3b1..29e6305187 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Test.java index 67c4dd868e..4b95513fe2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Issue289Test.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/289. @@ -40,10 +25,9 @@ SourceElement.class, TargetElement.class } ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue289Test { - @Test + @ProcessorTest public void shouldLeaveEmptyTargetSetWhenSourceIsNullAndGetterOnlyForCreateMethod() { Source source = new Source(); @@ -54,7 +38,7 @@ public void shouldLeaveEmptyTargetSetWhenSourceIsNullAndGetterOnlyForCreateMetho assertThat( target.getCollection() ).isEmpty(); } - @Test + @ProcessorTest public void shouldLeaveEmptyTargetSetWhenSourceIsNullAndGetterOnlyForUpdateMethod() { Source source = new Source(); @@ -67,7 +51,7 @@ public void shouldLeaveEmptyTargetSetWhenSourceIsNullAndGetterOnlyForUpdateMetho assertThat( target.getCollection() ).isEmpty(); } - @Test + @ProcessorTest public void shouldLeaveNullTargetSetWhenSourceIsNullForCreateMethod() { Source source = new Source(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Source.java index b9f2c3c2c5..76365a6354 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/SourceElement.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/SourceElement.java index 5ba6026f4a..453933e940 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/SourceElement.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/SourceElement.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetElement.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetElement.java index ee719e4e64..3131fffdf0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetElement.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetElement.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithSetter.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithSetter.java index 1355786fe3..6c9cdc7fd5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithSetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithSetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithoutSetter.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithoutSetter.java index c25d6509dc..c550662e83 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithoutSetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_289/TargetWithoutSetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._289; @@ -27,7 +14,7 @@ */ public class TargetWithoutSetter { - private final Collection collection = new ArrayList(); + private final Collection collection = new ArrayList<>(); public Collection getCollection() { return collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2891/Issue2891Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2891/Issue2891Mapper.java new file mode 100644 index 0000000000..205978aeb8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2891/Issue2891Mapper.java @@ -0,0 +1,76 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2891; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; + +/** + * @author Sergei Portnov + */ +@Mapper +public interface Issue2891Mapper { + + @BeanMapping(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) + @SubclassMapping(source = Source1.class, target = Target1.class) + @SubclassMapping(source = Source2.class, target = Target2.class) + AbstractTarget map(AbstractSource source); + + abstract class AbstractTarget { + + private final String name; + + protected AbstractTarget(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class Target1 extends AbstractTarget { + + protected Target1(String name) { + super( name ); + } + } + + class Target2 extends AbstractTarget { + + protected Target2(String name) { + super( name ); + } + } + + abstract class AbstractSource { + + private final String name; + + protected AbstractSource(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class Source1 extends AbstractSource { + protected Source1(String name) { + super( name ); + } + } + + class Source2 extends AbstractSource { + + protected Source2(String name) { + super( name ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2891/Issue2891Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2891/Issue2891Test.java new file mode 100644 index 0000000000..c82d5aa63e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2891/Issue2891Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2891; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author Sergei Portnov + */ +@WithClasses({ + Issue2891Mapper.class +}) +@IssueKey("2891") +class Issue2891Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( Issue2891Mapper.class ); + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Issue2897Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Issue2897Mapper.java new file mode 100644 index 0000000000..e13f2083ee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Issue2897Mapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2897; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.bugs._2897.util.Util; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(imports = Util.Factory.class) +public interface Issue2897Mapper { + + Issue2897Mapper INSTANCE = Mappers.getMapper( Issue2897Mapper.class ); + + @Mapping( target = "value", expression = "java(Factory.parse( source ))") + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Issue2897Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Issue2897Test.java new file mode 100644 index 0000000000..718ece4a90 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Issue2897Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2897; + +import org.mapstruct.ap.test.bugs._2897.util.Util; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2897") +@WithClasses({ + Util.class, + Issue2897Mapper.class, + Source.class, + Target.class, +}) +class Issue2897Test { + + @ProcessorTest + void shouldImportNestedClassInMapperImports() { + Target target = Issue2897Mapper.INSTANCE.map( new Source( "test" ) ); + + assertThat( target.getValue() ).isEqualTo( "parsed(test)" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Source.java new file mode 100644 index 0000000000..5d46ad1ba3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2897; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Target.java new file mode 100644 index 0000000000..71fbabbe57 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2897; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/util/Util.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/util/Util.java new file mode 100644 index 0000000000..5ef0c7e254 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2897/util/Util.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2897.util; + +import org.mapstruct.ap.test.bugs._2897.Source; + +/** + * @author Filip Hrisafov + */ +public class Util { + + public static class Factory { + + public static String parse(Source source) { + return source == null ? null : "parsed(" + source.getValue() + ")"; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/ConditionWithTargetTypeOnCollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/ConditionWithTargetTypeOnCollectionMapper.java new file mode 100644 index 0000000000..7e833cfc53 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/ConditionWithTargetTypeOnCollectionMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2901; + +import java.util.List; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.TargetType; + +@Mapper +public interface ConditionWithTargetTypeOnCollectionMapper { + + Target map(Source source); + + @Condition + default boolean check(List test, @TargetType Class type) { + return type.isInstance( test ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Issue2901Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Issue2901Test.java new file mode 100644 index 0000000000..3ae2c3db86 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Issue2901Test.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2901; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Ben Zegveld + */ +@IssueKey( "2901" ) +class Issue2901Test { + + @ProcessorTest + @WithClasses( { Source.class, Target.class, ConditionWithTargetTypeOnCollectionMapper.class } ) + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Source.java new file mode 100644 index 0000000000..4eb50d58fb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Source.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2901; + +import java.util.List; + +public class Source { + + private List field; + + public List getField() { + return field; + } + + public void setField(List field) { + this.field = field; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Target.java new file mode 100644 index 0000000000..b4c5299f35 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2901/Target.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2901; + +import java.util.List; + +public class Target { + + private List field; + + public List getField() { + return field; + } + + public void setField(List field) { + this.field = field; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Issue2907Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Issue2907Test.java new file mode 100644 index 0000000000..a005b6a1ad --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Issue2907Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2907; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.bugs._2907.mapper.Issue2907Mapper; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2907") +@WithClasses({ + Issue2907Mapper.class, + Source.class, + SourceNested.class, + Target.class, +}) +class Issue2907Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + void shouldNotGeneratedImportForNestedClass() { + generatedSource.forMapper( Issue2907Mapper.class ) + .containsNoImportFor( Target.TargetNested.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Source.java new file mode 100644 index 0000000000..42d015fde7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Source.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2907; + +import java.util.Set; + +public class Source { + + private Set nested; + + public Set getNested() { + return nested; + } + + public void setNested(Set nested) { + this.nested = nested; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/SourceNested.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/SourceNested.java new file mode 100644 index 0000000000..a58a94f0f3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/SourceNested.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2907; + +public class SourceNested { + + private String prop; + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Target.java new file mode 100644 index 0000000000..80a796d20d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/Target.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2907; + +public class Target { + + private TargetNested[] nested; + + public TargetNested[] getNested() { + return nested; + } + + public void setNested(TargetNested[] nested) { + this.nested = nested; + } + + public static class TargetNested { + private String prop; + + public String getProp() { + return prop; + } + + public void setProp(String prop) { + this.prop = prop; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/mapper/Issue2907Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/mapper/Issue2907Mapper.java new file mode 100644 index 0000000000..5244f95bb4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2907/mapper/Issue2907Mapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2907.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2907.Source; +import org.mapstruct.ap.test.bugs._2907.Target; + +@Mapper +public interface Issue2907Mapper { + + Target map(Source source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2913/Issue2913Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2913/Issue2913Mapper.java new file mode 100644 index 0000000000..095f5457fd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2913/Issue2913Mapper.java @@ -0,0 +1,85 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2913; + +import java.math.BigDecimal; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2913Mapper { + + Issue2913Mapper INSTANCE = Mappers.getMapper( Issue2913Mapper.class ); + + @Mapping(target = "doublePrimitiveValue", source = "rounding") + @Mapping(target = "doubleValue", source = "rounding") + @Mapping(target = "longPrimitiveValue", source = "rounding") + @Mapping(target = "longValue", source = "rounding") + Target map(Source source); + + default Long mapAmount(BigDecimal amount) { + return amount != null ? amount.movePointRight( 2 ).longValue() : null; + } + + class Target { + + private double doublePrimitiveValue; + private Double doubleValue; + private long longPrimitiveValue; + private Long longValue; + + public double getDoublePrimitiveValue() { + return doublePrimitiveValue; + } + + public void setDoublePrimitiveValue(double doublePrimitiveValue) { + this.doublePrimitiveValue = doublePrimitiveValue; + } + + public Double getDoubleValue() { + return doubleValue; + } + + public void setDoubleValue(Double doubleValue) { + this.doubleValue = doubleValue; + } + + public long getLongPrimitiveValue() { + return longPrimitiveValue; + } + + public void setLongPrimitiveValue(long longPrimitiveValue) { + this.longPrimitiveValue = longPrimitiveValue; + } + + public Long getLongValue() { + return longValue; + } + + public void setLongValue(Long longValue) { + this.longValue = longValue; + } + } + + class Source { + + private final BigDecimal rounding; + + public Source(BigDecimal rounding) { + this.rounding = rounding; + } + + public BigDecimal getRounding() { + return rounding; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2913/Issue2913Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2913/Issue2913Test.java new file mode 100644 index 0000000000..7257c9ab7e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2913/Issue2913Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2913; + +import java.math.BigDecimal; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2913") +@WithClasses({ + Issue2913Mapper.class, +}) +class Issue2913Test { + + @ProcessorTest + void shouldNotWidenWithUserDefinedMethods() { + Issue2913Mapper.Source source = new Issue2913Mapper.Source( BigDecimal.valueOf( 10.543 ) ); + Issue2913Mapper.Target target = Issue2913Mapper.INSTANCE.map( source ); + + assertThat( target.getDoubleValue() ).isEqualTo( 10.543 ); + assertThat( target.getDoublePrimitiveValue() ).isEqualTo( 10.543 ); + assertThat( target.getLongValue() ).isEqualTo( 1054 ); + assertThat( target.getLongPrimitiveValue() ).isEqualTo( 1054 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2921/Issue2921Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2921/Issue2921Mapper.java new file mode 100644 index 0000000000..d686fcbc16 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2921/Issue2921Mapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2921; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2921Mapper { + + Issue2921Mapper INSTANCE = Mappers.getMapper( Issue2921Mapper.class ); + + Target map(Source source); + + default Short toShort(Integer value) { + throw new UnsupportedOperationException( "toShort method should not be used" ); + } + + class Source { + private final Integer value; + + public Source(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + } + + class Target { + private final int value; + + public Target(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2921/Issue2921Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2921/Issue2921Test.java new file mode 100644 index 0000000000..5b8dd0386c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2921/Issue2921Test.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2921; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2921") +@WithClasses({ + Issue2921Mapper.class, +}) +class Issue2921Test { + + @ProcessorTest + void shouldNotUseIntegerToShortForMappingIntegerToInt() { + Issue2921Mapper.Target target = Issue2921Mapper.INSTANCE.map( new Issue2921Mapper.Source( 10 ) ); + assertThat( target.getValue() ).isEqualTo( 10 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Issue2925Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Issue2925Mapper.java new file mode 100644 index 0000000000..d231413820 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Issue2925Mapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2925; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue2925Mapper { + + Issue2925Mapper INSTANCE = Mappers.getMapper( Issue2925Mapper.class ); + + Target map(Source source); + + static Optional toOptional(T value) { + return Optional.ofNullable( value ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Issue2925Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Issue2925Test.java new file mode 100644 index 0000000000..73d009d093 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Issue2925Test.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2925; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2925") +@WithClasses({ + Issue2925Mapper.class, + Source.class, + Target.class, +}) +class Issue2925Test { + + @ProcessorTest + void shouldUseOptionalWrappingMethod() { + Target target = Issue2925Mapper.INSTANCE.map( new Source( 10L ) ); + + assertThat( target.getValue() ) + .hasValue( 10L ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Source.java new file mode 100644 index 0000000000..c21ce67775 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Source.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2925; + +public class Source { + + private final long value; + + public Source(long value) { + this.value = value; + } + + public long getValue() { + return value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Target.java new file mode 100644 index 0000000000..4693a83fdb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2925/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2925; + +import java.util.Optional; + +public class Target { + + private Long value; + + public Optional getValue() { + return Optional.ofNullable( value ); + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + public void setValue(Optional value) { + this.value = value.orElse( null ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2937/Issue2937Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2937/Issue2937Mapper.java new file mode 100644 index 0000000000..95d767acb8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2937/Issue2937Mapper.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2937; + +import java.util.ArrayList; +import java.util.Collection; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue2937Mapper { + + Issue2937Mapper INSTANCE = Mappers.getMapper( Issue2937Mapper.class ); + + Target map(Source source); + + @Condition + default boolean isApplicable(Collection collection) { + return collection == null || collection.size() > 1; + } + + class Source { + private final Collection names; + + public Source(Collection names) { + this.names = names; + } + + public Collection getNames() { + return names; + } + + } + + class Target { + private final Collection names; + + public Target() { + this.names = new ArrayList<>(); + } + + public Collection getNames() { + return names; + } + + public void addName(String name) { + this.names.add( name ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2937/Issue2937Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2937/Issue2937Test.java new file mode 100644 index 0000000000..140575263c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2937/Issue2937Test.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2937; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2937") +@WithClasses({ + Issue2937Mapper.class, +}) +class Issue2937Test { + + @ProcessorTest + void shouldCorrectlyUseConditionalForAdder() { + List sourceNames = new ArrayList<>(); + sourceNames.add( "Tester 1" ); + Issue2937Mapper.Source source = new Issue2937Mapper.Source( sourceNames ); + Issue2937Mapper.Target target = Issue2937Mapper.INSTANCE.map( source ); + + assertThat( target.getNames() ).isEmpty(); + + sourceNames.add( "Tester 2" ); + + target = Issue2937Mapper.INSTANCE.map( source ); + + assertThat( target.getNames() ) + .containsExactly( "Tester 1", "Tester 2" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/Issue2945Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/Issue2945Mapper.java new file mode 100644 index 0000000000..604d546273 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/Issue2945Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2945; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._2945._target.Target; +import org.mapstruct.ap.test.bugs._2945.source.Source; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue2945Mapper { + + Issue2945Mapper INSTANCE = Mappers.getMapper( Issue2945Mapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/Issue2945Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/Issue2945Test.java new file mode 100644 index 0000000000..11dcf752c0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/Issue2945Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2945; + +import org.mapstruct.ap.test.bugs._2945._target.EnumHolder; +import org.mapstruct.ap.test.bugs._2945._target.Target; +import org.mapstruct.ap.test.bugs._2945.source.Source; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2945") +@WithClasses({ + EnumHolder.class, + Issue2945Mapper.class, + Source.class, + Target.class, +}) +class Issue2945Test { + + @ProcessorTest + void shouldCompile() { + Target target = Issue2945Mapper.INSTANCE.map( new Source( "VALUE_1" ) ); + + assertThat( target.getProperty() ).isEqualTo( EnumHolder.Property.VALUE_1 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/_target/EnumHolder.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/_target/EnumHolder.java new file mode 100644 index 0000000000..0b75e9ce36 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/_target/EnumHolder.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2945._target; + +public class EnumHolder { + public enum Property { + VALUE_1, + VALUE_2; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/_target/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/_target/Target.java new file mode 100644 index 0000000000..25b69eed29 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/_target/Target.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2945._target; + +public class Target { + private EnumHolder.Property property; + + public EnumHolder.Property getProperty() { + return property; + } + + public void setProperty(EnumHolder.Property property) { + this.property = property; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/source/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/source/Source.java new file mode 100644 index 0000000000..8364941ad1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2945/source/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2945.source; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final String property; + + public Source(String property) { + this.property = property; + } + + public String getProperty() { + return property; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2949/Issue2949Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2949/Issue2949Mapper.java new file mode 100644 index 0000000000..553563066e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2949/Issue2949Mapper.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2949; + +import org.mapstruct.BeanMapping; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface Issue2949Mapper { + + Issue2949Mapper INSTANCE = Mappers.getMapper( Issue2949Mapper.class ); + + @Mapping( target = "property1", ignore = true) + @InheritInverseConfiguration + Source toSource(Target target); + + @BeanMapping(ignoreUnmappedSourceProperties = { "property1" }) + Target toTarget(Source source); + + class Target { + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + private final String value; + private final String property1; + + public Source(String value, String property1) { + this.value = value; + this.property1 = property1; + } + + public String getValue() { + return value; + } + + public String getProperty1() { + return property1; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2949/Issue2949Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2949/Issue2949Test.java new file mode 100644 index 0000000000..2a277a4bfd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2949/Issue2949Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2949; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue2949Mapper.class +}) +class Issue2949Test { + + @ProcessorTest + void shouldCorrectlyInheritInverseBeanMappingWithIgnoreUnmappedSourceProeprties() { + Issue2949Mapper.Target target = Issue2949Mapper.INSTANCE.toTarget( new Issue2949Mapper.Source( + "test", + "first" + ) ); + + assertThat( target.getValue() ).isEqualTo( "test" ); + + Issue2949Mapper.Source source = Issue2949Mapper.INSTANCE.toSource( target ); + + assertThat( source.getValue() ).isEqualTo( "test" ); + assertThat( source.getProperty1() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2952/Issue2952Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2952/Issue2952Mapper.java new file mode 100644 index 0000000000..885d74448f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2952/Issue2952Mapper.java @@ -0,0 +1,62 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2952; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE) +public interface Issue2952Mapper { + + Issue2952Mapper INSTANCE = Mappers.getMapper( Issue2952Mapper.class ); + + Target map(Source source); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + private final Map attributes = new HashMap<>(); + private final List values = new ArrayList<>(); + private String value; + + public Map getAttributes() { + return Collections.unmodifiableMap( attributes ); + } + + public List getValues() { + return Collections.unmodifiableList( values ); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2952/Issue2952Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2952/Issue2952Test.java new file mode 100644 index 0000000000..7a517ec979 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2952/Issue2952Test.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2952; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2952") +@WithClasses({ + Issue2952Mapper.class +}) +class Issue2952Test { + + @ProcessorTest + void shouldCorrectIgnoreImmutableIterable() { + Issue2952Mapper.Target target = Issue2952Mapper.INSTANCE.map( new Issue2952Mapper.Source( "test" ) ); + + assertThat( target.getValue() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3015/Issue3015Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3015/Issue3015Mapper.java new file mode 100644 index 0000000000..1683db8f39 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3015/Issue3015Mapper.java @@ -0,0 +1,153 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3015; + +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation; + +/** + * @author orange add + */ +@Mapper +public interface Issue3015Mapper { + + @AnnotateWith( CustomMethodOnlyAnnotation.class ) + Target map(Source source); + + class Source { + + private NestedSource nested; + private List list; + private Stream stream; + private AnnotateSourceEnum annotateWithEnum; + private Map map; + + public NestedSource getNested() { + return nested; + } + + public void setNested(NestedSource nested) { + this.nested = nested; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public Stream getStream() { + return stream; + } + + public void setStream(Stream stream) { + this.stream = stream; + } + + public AnnotateSourceEnum getAnnotateWithEnum() { + return annotateWithEnum; + } + + public void setAnnotateWithEnum(AnnotateSourceEnum annotateWithEnum) { + this.annotateWithEnum = annotateWithEnum; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + } + + class Target { + private NestedTarget nested; + private List list; + private Stream stream; + private AnnotateTargetEnum annotateWithEnum; + private Map map; + + public NestedTarget getNested() { + return nested; + } + + public void setNested(NestedTarget nested) { + this.nested = nested; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public Stream getStream() { + return stream; + } + + public void setStream(Stream stream) { + this.stream = stream; + } + + public AnnotateTargetEnum getAnnotateWithEnum() { + return annotateWithEnum; + } + + public void setAnnotateWithEnum(AnnotateTargetEnum annotateWithEnum) { + this.annotateWithEnum = annotateWithEnum; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + } + + enum AnnotateSourceEnum { + EXISTING; + } + + enum AnnotateTargetEnum { + EXISTING; + } + + class NestedSource { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class NestedTarget { + private Integer value; + + public Integer getValue() { + return value; + } + + public void setValue(Integer value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3015/Issue3015Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3015/Issue3015Test.java new file mode 100644 index 0000000000..96004b8c2d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3015/Issue3015Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3015; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.mapstruct.ap.test.annotatewith.CustomMethodOnlyAnnotation; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author orange add + */ +@WithClasses({ + Issue3015Mapper.class, + CustomMethodOnlyAnnotation.class +}) +class Issue3015Test { + + @ProcessorTest + void noNeedPassAnnotationToForgeMethod() { + Issue3015Mapper mapper = Mappers.getMapper( Issue3015Mapper.class ); + Method[] declaredMethods = mapper.getClass().getDeclaredMethods(); + List annotationMethods = Arrays.stream( declaredMethods ) + .filter( method -> method.getAnnotation( CustomMethodOnlyAnnotation.class ) != null ) + .collect( Collectors.toList() ); + assertThat( annotationMethods ).hasSize( 1 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3057/Issue3057Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3057/Issue3057Mapper.java new file mode 100644 index 0000000000..d8c444d8c5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3057/Issue3057Mapper.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3057; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface Issue3057Mapper { + + Issue3057Mapper INSTANCE = Mappers.getMapper( Issue3057Mapper.class ); + + class Source { + private Source self; + + public Source getSelf() { + return self; + } + + public void setSelf(Source self) { + this.self = self; + } + } + + class Target { + private Target self; + private String value; + + public Target getSelf() { + return self; + } + + public void setSelf(Target self) { + this.self = self; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + @Mapping( target = "value", constant = "constantValue" ) + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3057/Issue3057MapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3057/Issue3057MapperTest.java new file mode 100644 index 0000000000..7e64f529f3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3057/Issue3057MapperTest.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3057; + +import org.mapstruct.ap.test.bugs._3057.Issue3057Mapper.Source; +import org.mapstruct.ap.test.bugs._3057.Issue3057Mapper.Target; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Ben Zegveld + */ +@WithClasses(Issue3057Mapper.class) +@IssueKey("3057") +class Issue3057MapperTest { + + @ProcessorTest + void mapsSelf() { + Source sourceOuter = new Issue3057Mapper.Source(); + Source sourceInner = new Issue3057Mapper.Source(); + sourceOuter.setSelf( sourceInner ); + + Target targetOuter = Issue3057Mapper.INSTANCE.map( sourceOuter ); + + assertThat( targetOuter.getValue() ).isEqualTo( "constantValue" ); + assertThat( targetOuter.getSelf().getValue() ).isEqualTo( "constantValue" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Mapper.java index 4669f7677e..9d0b9a2574 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._306; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Test.java index d775baa747..5d4f0c84b2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Issue306Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._306; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/306. @@ -30,10 +15,9 @@ * @author Sjaak Derksen */ @IssueKey( "306" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue306Test { - @Test + @ProcessorTest @WithClasses( { Issue306Mapper.class, Source.class, Target.class } ) public void shouldForgeNewIterableMappingMethod() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Source.java index 8b3c6f6485..741e54fe3b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._306; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Target.java index 14092b3699..50196032b5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_306/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._306; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3077/Issue3077Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3077/Issue3077Mapper.java new file mode 100644 index 0000000000..f1a630a444 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3077/Issue3077Mapper.java @@ -0,0 +1,65 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3077; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3077Mapper { + + Issue3077Mapper INSTANCE = Mappers.getMapper( Issue3077Mapper.class ); + + class Source { + private final String source; + private final Source self; + + public Source(String source, Source self) { + this.source = source; + this.self = self; + } + + public String getSource() { + return source; + } + + public Source getSelf() { + return self; + } + } + + class Target { + private String value; + private Target self; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Target getSelf() { + return self; + } + + public void setSelf(Target self) { + this.self = self; + } + + } + + @Named("self") + @Mapping(target = "value", source = "source") + @Mapping(target = "self", qualifiedByName = "self") + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3077/Issue3077MapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3077/Issue3077MapperTest.java new file mode 100644 index 0000000000..bfba7988aa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3077/Issue3077MapperTest.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3077; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3077Mapper.class) +@IssueKey("3057") +class Issue3077MapperTest { + + @ProcessorTest + void mapsSelf() { + Issue3077Mapper.Source sourceInner = new Issue3077Mapper.Source( "inner", null ); + Issue3077Mapper.Source sourceOuter = new Issue3077Mapper.Source( "outer", sourceInner ); + + Issue3077Mapper.Target targetOuter = Issue3077Mapper.INSTANCE.map( sourceOuter ); + + assertThat( targetOuter.getValue() ).isEqualTo( "outer" ); + assertThat( targetOuter.getSelf().getValue() ).isEqualTo( "inner" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/Issue3089BuilderProvider.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/Issue3089BuilderProvider.java new file mode 100644 index 0000000000..52f0f96345 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/Issue3089BuilderProvider.java @@ -0,0 +1,96 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089; + +import java.util.List; +import java.util.Objects; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; + +import org.mapstruct.ap.spi.BuilderInfo; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesBuilderProvider; + +/** + * @author Oliver Erhart + */ +public class Issue3089BuilderProvider extends ImmutablesBuilderProvider implements BuilderProvider { + + @Override + protected BuilderInfo findBuilderInfo(TypeElement typeElement) { + Name name = typeElement.getQualifiedName(); + if ( name.toString().endsWith( ".Item" ) ) { + BuilderInfo info = findBuilderInfoFromInnerBuilderClass( typeElement ); + if ( info != null ) { + return info; + } + } + return super.findBuilderInfo( typeElement ); + } + + /** + * Looks for inner builder class in the Immutable interface / abstract class. + * + * The inner builder class should be be declared with the following line + * + *

      +     *     public static Builder() extends ImmutableItem.Builder { }
      +     * 
      + * + * The Immutable instance should be created with the following line + * + *
      +     *     new Item.Builder().withId("123").build();
      +     * 
      + * + * @see org.mapstruct.ap.test.bugs._3089.domain.Item + * + * @param typeElement + * @return + */ + private BuilderInfo findBuilderInfoFromInnerBuilderClass(TypeElement typeElement) { + if ( shouldIgnore( typeElement ) ) { + return null; + } + + List innerTypes = ElementFilter.typesIn( typeElement.getEnclosedElements() ); + ExecutableElement defaultConstructor = innerTypes.stream() + .filter( this::isBuilderCandidate ) + .map( this::getEmptyArgPublicConstructor ) + .filter( Objects::nonNull ) + .findAny() + .orElse( null ); + + if ( defaultConstructor != null ) { + return new BuilderInfo.Builder() + .builderCreationMethod( defaultConstructor ) + .buildMethod( findBuildMethods( (TypeElement) defaultConstructor.getEnclosingElement(), typeElement ) ) + .build(); + } + return null; + } + + private boolean isBuilderCandidate(TypeElement innerType ) { + TypeElement outerType = (TypeElement) innerType.getEnclosingElement(); + String packageName = this.elementUtils.getPackageOf( outerType ).getQualifiedName().toString(); + Name outerSimpleName = outerType.getSimpleName(); + String builderClassName = packageName + ".Immutable" + outerSimpleName + ".Builder"; + return innerType.getSimpleName().contentEquals( "Builder" ) + && getTypeElement( innerType.getSuperclass() ).getQualifiedName().contentEquals( builderClassName ) + && innerType.getModifiers().contains( Modifier.PUBLIC ); + } + + private ExecutableElement getEmptyArgPublicConstructor(TypeElement builderType) { + return ElementFilter.constructorsIn( builderType.getEnclosedElements() ).stream() + .filter( c -> c.getParameters().isEmpty() ) + .filter( c -> c.getModifiers().contains( Modifier.PUBLIC ) ) + .findAny() + .orElse( null ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/Issue3089Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/Issue3089Test.java new file mode 100644 index 0000000000..f7c138c146 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/Issue3089Test.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089; + +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.ap.spi.AccessorNamingStrategy; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy; +import org.mapstruct.ap.test.bugs._3089.domain.ImmutableItem; +import org.mapstruct.ap.test.bugs._3089.domain.Item; +import org.mapstruct.ap.test.bugs._3089.dto.ImmutableItemDTO; +import org.mapstruct.ap.test.bugs._3089.dto.ItemDTO; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.WithServiceImplementations; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Oliver Erhart + */ +@WithClasses({ + ItemMapper.class, + Item.class, + ImmutableItem.class, + ItemDTO.class, + ImmutableItemDTO.class +}) +@IssueKey("3089") +@WithServiceImplementations({ + @WithServiceImplementation(provides = BuilderProvider.class, value = Issue3089BuilderProvider.class), + @WithServiceImplementation(provides = AccessorNamingStrategy.class, value = ImmutablesAccessorNamingStrategy.class) +}) +public class Issue3089Test { + + @ProcessorTest + public void shouldIgnorePutterOfMap() { + + Map attributesMap = new HashMap<>(); + attributesMap.put( "a", "b" ); + attributesMap.put( "c", "d" ); + + ItemDTO item = ImmutableItemDTO.builder() + .id( "test" ) + .attributes( attributesMap ) + .build(); + + Item target = ItemMapper.INSTANCE.map( item ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( "test" ); + assertThat( target.getAttributes() ).isEqualTo( attributesMap ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/ItemMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/ItemMapper.java new file mode 100644 index 0000000000..ed06115ae2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/ItemMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089; + +import org.mapstruct.Builder; +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._3089.domain.Item; +import org.mapstruct.ap.test.bugs._3089.dto.ItemDTO; +import org.mapstruct.factory.Mappers; + +/** + * @author Oliver Erhart + */ +@Mapper(builder = @Builder) +public abstract class ItemMapper { + + public static final ItemMapper INSTANCE = Mappers.getMapper( ItemMapper.class ); + + public abstract Item map(ItemDTO itemDTO); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/domain/ImmutableItem.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/domain/ImmutableItem.java new file mode 100644 index 0000000000..ab5a6afdc0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/domain/ImmutableItem.java @@ -0,0 +1,296 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Immutable implementation of {@link Item}. + *

      + * Superclass should expose a static subclass of the Builder to create immutable instance + * {@code public static Builder extends ImmutableItem.Builder}. + * + * @author Oliver Erhart + */ +@SuppressWarnings({"all"}) +public final class ImmutableItem extends Item { + private final String id; + private final Map attributes; + + private ImmutableItem(String id, Map attributes) { + this.id = id; + this.attributes = attributes; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * @return The value of the {@code attributes} attribute + */ + @Override + public Map getAttributes() { + return attributes; + } + + /** + * Copy the current immutable object by setting a value for the {@link Item#getId() id} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * @param value A new value for id + * @return A modified copy of the {@code this} object + */ + public final ImmutableItem withId(String value) { + String newValue = Objects.requireNonNull(value, "id"); + if (this.id.equals(newValue)) return this; + return new ImmutableItem(newValue, this.attributes); + } + + /** + * Copy the current immutable object by replacing the {@link Item#getAttributes() attributes} map with the specified map. + * Nulls are not permitted as keys or values. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * @param entries The entries to be added to the attributes map + * @return A modified copy of {@code this} object + */ + public final ImmutableItem withAttributes(Map entries) { + if (this.attributes == entries) return this; + Map newValue = createUnmodifiableMap(true, false, entries); + return new ImmutableItem(this.id, newValue); + } + + /** + * This instance is equal to all instances of {@code ImmutableItem} that have equal attribute values. + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if (this == another) return true; + return another instanceof ImmutableItem + && equalTo((ImmutableItem) another); + } + + private boolean equalTo(ImmutableItem another) { + return id.equals(another.id) + && attributes.equals(another.attributes); + } + + /** + * Computes a hash code from attributes: {@code id}, {@code attributes}. + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 5381; + h += (h << 5) + id.hashCode(); + h += (h << 5) + attributes.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code Item} with attribute values. + * @return A string representation of the value + */ + @Override + public String toString() { + return "Item{" + + "id=" + id + + ", attributes=" + attributes + + "}"; + } + + /** + * Creates an immutable copy of a {@link Item} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * @param instance The instance to copy + * @return A copied immutable Item instance + */ + public static ImmutableItem copyOf(Item instance) { + if (instance instanceof ImmutableItem) { + return (ImmutableItem) instance; + } + return ImmutableItem.builder() + .from(instance) + .build(); + } + + /** + * Creates a builder for {@link ImmutableItem ImmutableItem}. + *

      +   * ImmutableItem.builder()
      +   *    .id(String) // required {@link Item#getId() id}
      +   *    .putAttributes|putAllAttributes(String => String) // {@link Item#getAttributes() attributes} mappings
      +   *    .build();
      +   * 
      + * @return A new ImmutableItem builder + */ + public static ImmutableItem.Builder builder() { + return new ImmutableItem.Builder(); + } + + /** + * Builds instances of type {@link ImmutableItem ImmutableItem}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + private Map attributes = new LinkedHashMap(); + + public Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code Item} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * Collection elements and entries will be added, not replaced. + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Builder from(Item instance) { + Objects.requireNonNull(instance, "instance"); + id(instance.getId()); + putAllAttributes(instance.getAttributes()); + return this; + } + + /** + * Initializes the value for the {@link Item#getId() id} attribute. + * @param id The value for id + * @return {@code this} builder for use in a chained invocation + */ + public final Builder id(String id) { + this.id = Objects.requireNonNull(id, "id"); + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Put one entry to the {@link Item#getAttributes() attributes} map. + * @param key The key in the attributes map + * @param value The associated value in the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final Builder putAttributes(String key, String value) { + this.attributes.put( + Objects.requireNonNull(key, "attributes key"), + Objects.requireNonNull(value, "attributes value")); + return this; + } + + /** + * Put one entry to the {@link Item#getAttributes() attributes} map. Nulls are not permitted + * @param entry The key and value entry + * @return {@code this} builder for use in a chained invocation + */ + public final Builder putAttributes(Map.Entry entry) { + String k = entry.getKey(); + String v = entry.getValue(); + this.attributes.put( + Objects.requireNonNull(k, "attributes key"), + Objects.requireNonNull(v, "attributes value")); + return this; + } + + /** + * Sets or replaces all mappings from the specified map as entries for the {@link Item#getAttributes() attributes} map. Nulls are not permitted + * @param entries The entries that will be added to the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final Builder attributes(Map entries) { + this.attributes.clear(); + return putAllAttributes(entries); + } + + /** + * Put all mappings from the specified map as entries to {@link Item#getAttributes() attributes} map. Nulls are not permitted + * @param entries The entries that will be added to the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final Builder putAllAttributes(Map entries) { + for (Map.Entry e : entries.entrySet()) { + String k = e.getKey(); + String v = e.getValue(); + this.attributes.put( + Objects.requireNonNull(k, "attributes key"), + Objects.requireNonNull(v, "attributes value")); + } + return this; + } + + /** + * Builds a new {@link ImmutableItem ImmutableItem}. + * @return An immutable instance of Item + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItem build() { + if (initBits != 0) { + throw new IllegalStateException(formatRequiredAttributesMessage()); + } + return new ImmutableItem(id, createUnmodifiableMap(false, false, attributes)); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ((initBits & INIT_BIT_ID) != 0) attributes.add("id"); + return "Cannot build Item, some of required attributes are not set " + attributes; + } + } + + private static Map createUnmodifiableMap(boolean checkNulls, boolean skipNulls, Map map) { + switch (map.size()) { + case 0: return Collections.emptyMap(); + case 1: { + Map.Entry e = map.entrySet().iterator().next(); + K k = e.getKey(); + V v = e.getValue(); + if (checkNulls) { + Objects.requireNonNull(k, "key"); + Objects.requireNonNull(v, "value"); + } + if (skipNulls && (k == null || v == null)) { + return Collections.emptyMap(); + } + return Collections.singletonMap(k, v); + } + default: { + Map linkedMap = new LinkedHashMap<>(map.size()); + if (skipNulls || checkNulls) { + for (Map.Entry e : map.entrySet()) { + K k = e.getKey(); + V v = e.getValue(); + if (skipNulls) { + if (k == null || v == null) continue; + } else if (checkNulls) { + Objects.requireNonNull(k, "key"); + Objects.requireNonNull(v, "value"); + } + linkedMap.put(k, v); + } + } else { + linkedMap.putAll(map); + } + return Collections.unmodifiableMap(linkedMap); + } + } + } +} \ No newline at end of file diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/domain/Item.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/domain/Item.java new file mode 100644 index 0000000000..e193432367 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/domain/Item.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089.domain; + +import java.util.Map; + +/** + * @author Oliver Erhart + */ +public abstract class Item { + public abstract String getId(); + + public abstract Map getAttributes(); + + public static class Builder extends ImmutableItem.Builder { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/dto/ImmutableItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/dto/ImmutableItemDTO.java new file mode 100644 index 0000000000..de64727bf1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/dto/ImmutableItemDTO.java @@ -0,0 +1,330 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089.dto; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Immutable implementation of {@link ItemDTO}. + *

      + * Use the builder to create immutable instances: + * {@code ImmutableItemDTO.builder()}. + * + * @author Oliver Erhart + */ +public final class ImmutableItemDTO extends ItemDTO { + private final String id; + private final Map attributes; + + private ImmutableItemDTO(String id, Map attributes) { + this.id = id; + this.attributes = attributes; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * @return The value of the {@code attributes} attribute + */ + @Override + public Map getAttributes() { + return attributes; + } + + /** + * Copy the current immutable object by setting a value for the {@link ItemDTO#getId() id} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * + * @param value A new value for id + * @return A modified copy of the {@code this} object + */ + public ImmutableItemDTO withId(String value) { + String newValue = Objects.requireNonNull( value, "id" ); + if ( this.id.equals( newValue ) ) { + return this; + } + return new ImmutableItemDTO( newValue, this.attributes ); + } + + /** + * Copy the current immutable object by replacing the {@link ItemDTO#getAttributes() attributes} map with + * the specified map. + * Nulls are not permitted as keys or values. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * + * @param entries The entries to be added to the attributes map + * @return A modified copy of {@code this} object + */ + public ImmutableItemDTO withAttributes(Map entries) { + if ( this.attributes == entries ) { + return this; + } + Map newValue = createUnmodifiableMap( true, false, entries ); + return new ImmutableItemDTO( this.id, newValue ); + } + + /** + * This instance is equal to all instances of {@code ImmutableItemDTO} that have equal attribute values. + * + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if ( this == another ) { + return true; + } + return another instanceof ImmutableItemDTO + && equalTo( (ImmutableItemDTO) another ); + } + + private boolean equalTo(ImmutableItemDTO another) { + return id.equals( another.id ) + && attributes.equals( another.attributes ); + } + + /** + * Computes a hash code from attributes: {@code id}, {@code attributes}. + * + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 5381; + h += ( h << 5 ) + id.hashCode(); + h += ( h << 5 ) + attributes.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code Item} with attribute values. + * + * @return A string representation of the value + */ + @Override + public String toString() { + return "Item{" + + "id=" + id + + ", attributes=" + attributes + + "}"; + } + + /** + * Creates an immutable copy of a {@link ItemDTO} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * + * @param instance The instance to copy + * @return A copied immutable Item instance + */ + public static ImmutableItemDTO copyOf(ItemDTO instance) { + if ( instance instanceof ImmutableItemDTO ) { + return (ImmutableItemDTO) instance; + } + return ImmutableItemDTO.builder() + .from( instance ) + .build(); + } + + /** + * Creates a builder for {@link ImmutableItemDTO ImmutableItemDTO}. + *

      +     * ImmutableItemDTO.builder()
      +     *    .id(String) // required {@link ItemDTO#getId() id}
      +     *    .putAttributes|putAllAttributes(String => String) // {@link ItemDTO#getAttributes() attributes} mappings
      +     *    .build();
      +     * 
      + * + * @return A new ImmutableItemDTO builder + */ + public static ImmutableItemDTO.Builder builder() { + return new ImmutableItemDTO.Builder(); + } + + /** + * Builds instances of type {@link ImmutableItemDTO ImmutableItemDTO}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + private Map attributes = new LinkedHashMap(); + + public Builder() { + } + + /** + * Fill a builder with attribute values from the provided {@code Item} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * Collection elements and entries will be added, not replaced. + * + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final ImmutableItemDTO.Builder from(ItemDTO instance) { + Objects.requireNonNull( instance, "instance" ); + id( instance.getId() ); + putAllAttributes( instance.getAttributes() ); + return this; + } + + /** + * Initializes the value for the {@link ItemDTO#getId() id} attribute. + * + * @param id The value for id + * @return {@code this} builder for use in a chained invocation + */ + public final ImmutableItemDTO.Builder id(String id) { + this.id = Objects.requireNonNull( id, "id" ); + initBits &= ~INIT_BIT_ID; + return this; + } + + /** + * Put one entry to the {@link ItemDTO#getAttributes() attributes} map. + * + * @param key The key in the attributes map + * @param value The associated value in the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final ImmutableItemDTO.Builder putAttributes(String key, String value) { + this.attributes.put( + Objects.requireNonNull( key, "attributes key" ), + Objects.requireNonNull( value, "attributes value" ) + ); + return this; + } + + /** + * Put one entry to the {@link ItemDTO#getAttributes() attributes} map. Nulls are not permitted + * + * @param entry The key and value entry + * @return {@code this} builder for use in a chained invocation + */ + public final ImmutableItemDTO.Builder putAttributes(Map.Entry entry) { + String k = entry.getKey(); + String v = entry.getValue(); + this.attributes.put( + Objects.requireNonNull( k, "attributes key" ), + Objects.requireNonNull( v, "attributes value" ) + ); + return this; + } + + /** + * Sets or replaces all mappings from the specified map as entries for the {@link ItemDTO#getAttributes() + * attributes} map. Nulls are not permitted + * + * @param entries The entries that will be added to the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final ImmutableItemDTO.Builder attributes(Map entries) { + this.attributes.clear(); + return putAllAttributes( entries ); + } + + /** + * Put all mappings from the specified map as entries to {@link ItemDTO#getAttributes() attributes} map. + * Nulls are not permitted + * + * @param entries The entries that will be added to the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final ImmutableItemDTO.Builder putAllAttributes(Map entries) { + for ( Map.Entry e : entries.entrySet() ) { + String k = e.getKey(); + String v = e.getValue(); + this.attributes.put( + Objects.requireNonNull( k, "attributes key" ), + Objects.requireNonNull( v, "attributes value" ) + ); + } + return this; + } + + /** + * Builds a new {@link ImmutableItemDTO ImmutableItemDTO}. + * + * @return An immutable instance of Item + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItemDTO build() { + if ( initBits != 0 ) { + throw new IllegalStateException( formatRequiredAttributesMessage() ); + } + return new ImmutableItemDTO( id, createUnmodifiableMap( false, false, attributes ) ); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ( ( initBits & INIT_BIT_ID ) != 0 ) { + attributes.add( "id" ); + } + return "Cannot build Item, some of required attributes are not set " + attributes; + } + } + + @SuppressWarnings( "checkstyle:AvoidNestedBlocks" ) + private static Map createUnmodifiableMap(boolean checkNulls, boolean skipNulls, + Map map) { + switch ( map.size() ) { + case 0: + return Collections.emptyMap(); + case 1: { + Map.Entry e = map.entrySet().iterator().next(); + K k = e.getKey(); + V v = e.getValue(); + if ( checkNulls ) { + Objects.requireNonNull( k, "key" ); + Objects.requireNonNull( v, "value" ); + } + if ( skipNulls && ( k == null || v == null ) ) { + return Collections.emptyMap(); + } + return Collections.singletonMap( k, v ); + } + default: { + Map linkedMap = new LinkedHashMap<>( map.size() ); + if ( skipNulls || checkNulls ) { + for ( Map.Entry e : map.entrySet() ) { + K k = e.getKey(); + V v = e.getValue(); + if ( skipNulls ) { + if ( k == null || v == null ) { + continue; + } + } + else if ( checkNulls ) { + Objects.requireNonNull( k, "key" ); + Objects.requireNonNull( v, "value" ); + } + linkedMap.put( k, v ); + } + } + else { + linkedMap.putAll( map ); + } + return Collections.unmodifiableMap( linkedMap ); + } + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/dto/ItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/dto/ItemDTO.java new file mode 100644 index 0000000000..c38e37f08a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3089/dto/ItemDTO.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3089.dto; + +import java.util.Map; + +/** + * @author Oliver Erhart + */ +public abstract class ItemDTO { + public abstract String getId(); + + public abstract Map getAttributes(); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3104/Issue3104Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3104/Issue3104Mapper.java new file mode 100644 index 0000000000..e561f40bab --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3104/Issue3104Mapper.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3104; + +import java.util.Collections; +import java.util.List; + +import org.mapstruct.BeanMapping; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE) +public interface Issue3104Mapper { + + Issue3104Mapper INSTANCE = Mappers.getMapper( Issue3104Mapper.class ); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + void update(@MappingTarget Target target, Source source); + + class Target { + private List children = Collections.emptyList(); + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + if ( children == null ) { + throw new IllegalArgumentException( "children is null" ); + } + this.children = Collections.unmodifiableList( children ); + } + } + + class Child { + private String myField; + + public String getMyField() { + return myField; + } + + public void setMyField(String myField) { + this.myField = myField; + } + } + + class Source { + private final List children; + + public Source(List children) { + this.children = children; + } + + public List getChildren() { + return children; + } + + } + + class ChildSource { + private final String myField; + + public ChildSource(String myField) { + this.myField = myField; + } + + public String getMyField() { + return myField; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3104/Issue3104Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3104/Issue3104Test.java new file mode 100644 index 0000000000..5f3a9e160b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3104/Issue3104Test.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3104; + +import java.util.Collections; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3104") +@WithClasses(Issue3104Mapper.class) +class Issue3104Test { + + @ProcessorTest + void shouldCorrectlyMapUpdateMappingWithTargetImmutableCollectionStrategy() { + Issue3104Mapper.Target target = new Issue3104Mapper.Target(); + Issue3104Mapper.INSTANCE.update( target, new Issue3104Mapper.Source( null ) ); + + assertThat( target.getChildren() ).isEmpty(); + + Issue3104Mapper.INSTANCE.update( + target, + new Issue3104Mapper.Source( Collections.singletonList( new Issue3104Mapper.ChildSource( "tester" ) ) ) + ); + assertThat( target.getChildren() ) + .extracting( Issue3104Mapper.Child::getMyField ) + .containsExactly( "tester" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3110/Issue3110Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3110/Issue3110Mapper.java new file mode 100644 index 0000000000..12dd823760 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3110/Issue3110Mapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3110; + +import org.mapstruct.EnumMapping; +import org.mapstruct.Mapper; + +@Mapper +public interface Issue3110Mapper { + enum SourceEnum { + FOO, BAR + } + + enum TargetEnum { + FOO, BAR + } + + class CustomCheckedException extends Exception { + public CustomCheckedException(String message) { + super( message ); + } + } + + @EnumMapping(unexpectedValueMappingException = CustomCheckedException.class) + TargetEnum map(SourceEnum sourceEnum) throws CustomCheckedException; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3110/Issue3110MapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3110/Issue3110MapperTest.java new file mode 100644 index 0000000000..3b256ba100 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3110/Issue3110MapperTest.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3110; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +@WithClasses({ + Issue3110Mapper.class +}) +@IssueKey("3110") +class Issue3110MapperTest { + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + void throwsException() { + generatedSource.forMapper( Issue3110Mapper.class ).content() + .contains( "throws CustomCheckedException" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3126/Issue3126Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3126/Issue3126Mapper.java new file mode 100644 index 0000000000..e680db9317 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3126/Issue3126Mapper.java @@ -0,0 +1,92 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3126; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; +import org.mapstruct.factory.Mappers; + +@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) +public interface Issue3126Mapper { + + Issue3126Mapper INSTANCE = Mappers.getMapper( Issue3126Mapper.class ); + + @SubclassMapping(target = HomeAddressDto.class, source = HomeAddress.class) + @SubclassMapping(target = OfficeAddressDto.class, source = OfficeAddress.class) + @Mapping(target = ".", source = "auditable") + AddressDto map(Address address); + + interface AddressDto { + + } + + class HomeAddressDto implements AddressDto { + private String createdBy; + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + } + + class OfficeAddressDto implements AddressDto { + private String createdBy; + + public String getCreatedBy() { + return createdBy; + } + + public void setCreatedBy(String createdBy) { + this.createdBy = createdBy; + } + } + + class HomeAddress extends Address { + + public HomeAddress(Auditable auditable) { + super( auditable ); + } + } + + class OfficeAddress extends Address { + + public OfficeAddress(Auditable auditable) { + super( auditable ); + } + } + + abstract class Address { + + private final Auditable auditable; + + protected Address(Auditable auditable) { + this.auditable = auditable; + } + + public Auditable getAuditable() { + return auditable; + } + } + + class Auditable { + + private final String createdBy; + + public Auditable(String createdBy) { + this.createdBy = createdBy; + } + + public String getCreatedBy() { + return createdBy; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3126/Issue3126Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3126/Issue3126Test.java new file mode 100644 index 0000000000..35e3eb873c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3126/Issue3126Test.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3126; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3126") +@WithClasses(Issue3126Mapper.class) +class Issue3126Test { + + @ProcessorTest + void shouldCompile() { + Issue3126Mapper.Auditable auditable = new Issue3126Mapper.Auditable( "home-user" ); + Issue3126Mapper.Address address = new Issue3126Mapper.HomeAddress( auditable ); + Issue3126Mapper.AddressDto addressDto = Issue3126Mapper.INSTANCE.map( address ); + + assertThat( addressDto ).isInstanceOfSatisfying( Issue3126Mapper.HomeAddressDto.class, homeAddress -> { + assertThat( homeAddress.getCreatedBy() ).isEqualTo( "home-user" ); + } ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142Exception.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142Exception.java new file mode 100644 index 0000000000..54ed903ee7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142Exception.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3142; + +/** + * @author Filip Hrisafov + */ +public class Issue3142Exception extends Exception { + + public Issue3142Exception(String message) { + super( message ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142Test.java new file mode 100644 index 0000000000..a8b44874bb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142Test.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3142; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Issue3142Exception.class, + Source.class, + Target.class, +}) +@IssueKey("3142") +class Issue3142Test { + + @ProcessorTest + @WithClasses({ + Issue3142WithBeforeMappingExceptionMapper.class + }) + void exceptionThrownInBeforeMapping() { + assertThatThrownBy( () -> Issue3142WithBeforeMappingExceptionMapper.INSTANCE.map( + new Source( new Source.Nested( "throwException" ) ), "test" ) + ) + .isInstanceOf( Issue3142Exception.class ) + .hasMessage( "Source nested exception" ); + } + + @ProcessorTest + @WithClasses({ + Issue3142WithAfterMappingExceptionMapper.class + }) + void exceptionThrownInAfterMapping() { + assertThatThrownBy( () -> Issue3142WithAfterMappingExceptionMapper.INSTANCE.map( + new Source( new Source.Nested( "throwException" ) ), "test" ) + ) + .isInstanceOf( Issue3142Exception.class ) + .hasMessage( "Source nested exception" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142WithAfterMappingExceptionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142WithAfterMappingExceptionMapper.java new file mode 100644 index 0000000000..e188626424 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142WithAfterMappingExceptionMapper.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3142; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3142WithAfterMappingExceptionMapper { + + Issue3142WithAfterMappingExceptionMapper INSTANCE = + Mappers.getMapper( Issue3142WithAfterMappingExceptionMapper.class ); + + Target map(Source source, String id) throws Issue3142Exception; + + @AfterMapping + default void afterMappingValidation(Object source) throws Issue3142Exception { + if ( source instanceof Source.Nested ) { + Source.Nested nested = (Source.Nested) source; + if ( "throwException".equals( nested.getValue() ) ) { + throw new Issue3142Exception( "Source nested exception" ); + } + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142WithBeforeMappingExceptionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142WithBeforeMappingExceptionMapper.java new file mode 100644 index 0000000000..ee27d87b7f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Issue3142WithBeforeMappingExceptionMapper.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3142; + +import org.mapstruct.BeforeMapping; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3142WithBeforeMappingExceptionMapper { + + Issue3142WithBeforeMappingExceptionMapper INSTANCE = + Mappers.getMapper( Issue3142WithBeforeMappingExceptionMapper.class ); + + Target map(Source source, String id) throws Issue3142Exception; + + @BeforeMapping + default void preMappingValidation(Object source) throws Issue3142Exception { + if ( source instanceof Source.Nested ) { + Source.Nested nested = (Source.Nested) source; + if ( "throwException".equals( nested.getValue() ) ) { + throw new Issue3142Exception( "Source nested exception" ); + } + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Source.java new file mode 100644 index 0000000000..2b78ffa022 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Source.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3142; + +/** + * @author Filip Hrisafov + */ +public class Source { + private final Nested nested; + + public Source(Nested nested) { + this.nested = nested; + } + + public Nested getNested() { + return nested; + } + + public static class Nested { + private final String value; + + public Nested(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Target.java new file mode 100644 index 0000000000..6f832b6ecf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3142/Target.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3142; + +/** + * @author Filip Hrisafov + */ +public class Target { + private String id; + private Nested nested; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + + public static class Nested { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3144/Issue3144Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3144/Issue3144Mapper.java new file mode 100644 index 0000000000..df5b767876 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3144/Issue3144Mapper.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3144; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface Issue3144Mapper { + + Issue3144Mapper INSTANCE = Mappers.getMapper( Issue3144Mapper.class ); + + @Mapping(target = "map", source = "sourceMap") + Target mapExplicitDefined(Map sourceMap); + + @Mapping(target = "map", ignore = true) + Target map(Map sourceMap); + + Target mapMultiParameters(Source source, Map map); + + @Mapping(target = "value", source = "map.testValue") + Target mapMultiParametersDefinedMapping(Source source, Map map); + + class Source { + private final String sourceValue; + + public Source(String sourceValue) { + this.sourceValue = sourceValue; + } + + public String getSourceValue() { + return sourceValue; + } + } + + class Target { + private String value; + private Map map; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3144/Issue3144Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3144/Issue3144Test.java new file mode 100644 index 0000000000..13f349414a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3144/Issue3144Test.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3144; + +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3144Mapper.class) +@IssueKey("3144") +class Issue3144Test { + + @ProcessorTest + void shouldCorrectlyHandleMapBeanMapping() { + Map map = new HashMap<>(); + map.put( "value", "Map Value" ); + map.put( "testValue", "Map Test Value" ); + + Issue3144Mapper.Target target = Issue3144Mapper.INSTANCE.mapExplicitDefined( map ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "Map Value" ); + assertThat( target.getMap() ) + .containsOnly( + entry( "value", "Map Value" ), + entry( "testValue", "Map Test Value" ) + ); + + target = Issue3144Mapper.INSTANCE.map( map ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "Map Value" ); + assertThat( target.getMap() ).isNull(); + + target = Issue3144Mapper.INSTANCE.mapMultiParameters( null, map ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + assertThat( target.getMap() ) + .containsOnly( + entry( "value", "Map Value" ), + entry( "testValue", "Map Test Value" ) + ); + + target = Issue3144Mapper.INSTANCE.mapMultiParametersDefinedMapping( null, map ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "Map Test Value" ); + assertThat( target.getMap() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3153/Issue3153Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3153/Issue3153Mapper.java new file mode 100644 index 0000000000..af54d23a8d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3153/Issue3153Mapper.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3153; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +interface Issue3153Mapper { + + Issue3153Mapper INSTANCE = Mappers.getMapper( Issue3153Mapper.class ); + + @ValueMapping(source = " PR", target = "PR") + @ValueMapping(source = " PR", target = "PR") + @ValueMapping(source = " PR", target = "PR") + @ValueMapping(source = MappingConstants.ANY_REMAINING, target = MappingConstants.NULL) + Target mapToEnum(String value); + + @ValueMapping(source = "PR", target = " PR") + String mapFromEnum(Target value); + + enum Target { + PR, + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3153/Issue3153Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3153/Issue3153Test.java new file mode 100644 index 0000000000..658a497086 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3153/Issue3153Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3153; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3153Mapper.class) +@IssueKey("3153") +class Issue3153Test { + + @ProcessorTest + void shouldNotTrimStringValueSource() { + assertThat( Issue3153Mapper.INSTANCE.mapToEnum( "PR" ) ).isEqualTo( Issue3153Mapper.Target.PR ); + assertThat( Issue3153Mapper.INSTANCE.mapToEnum( " PR" ) ).isEqualTo( Issue3153Mapper.Target.PR ); + assertThat( Issue3153Mapper.INSTANCE.mapToEnum( " PR" ) ).isEqualTo( Issue3153Mapper.Target.PR ); + assertThat( Issue3153Mapper.INSTANCE.mapToEnum( " PR" ) ).isEqualTo( Issue3153Mapper.Target.PR ); + + assertThat( Issue3153Mapper.INSTANCE.mapFromEnum( Issue3153Mapper.Target.PR ) ).isEqualTo( " PR" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3158/Issue3158Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3158/Issue3158Mapper.java new file mode 100644 index 0000000000..25af6b3d44 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3158/Issue3158Mapper.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3158; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3158Mapper { + + Issue3158Mapper INSTANCE = Mappers.getMapper( Issue3158Mapper.class ); + + @BeanMapping(ignoreByDefault = true) + @Mapping(target = "name") + Target map(Target target); + + class Target { + private final String name; + private final String email; + + public Target(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public String getEmail() { + return email; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3158/Issue3158Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3158/Issue3158Test.java new file mode 100644 index 0000000000..e4832edfa9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3158/Issue3158Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3158; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3158Mapper.class) +@IssueKey("3158") +class Issue3158Test { + + @ProcessorTest + void beanMappingIgnoreByDefaultShouldBeRespectedForConstructorProperties() { + Issue3158Mapper.Target target = Issue3158Mapper.INSTANCE.map( new Issue3158Mapper.Target( + "tester", + "tester@test.com" + ) ); + + assertThat( target.getName() ).isEqualTo( "tester" ); + assertThat( target.getEmail() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3159/Issue3159Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3159/Issue3159Mapper.java new file mode 100644 index 0000000000..42c77c71dd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3159/Issue3159Mapper.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3159; + +import java.util.Collection; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3159Mapper { + + Issue3159Mapper INSTANCE = Mappers.getMapper( Issue3159Mapper.class ); + + @Mapping(target = "elements", defaultExpression = "java(new ArrayList<>())") + Target map(Source source); + + default String elementName(Element element) { + return element != null ? element.getName() : null; + } + + class Target { + private final Collection elements; + + public Target(Collection elements) { + this.elements = elements; + } + + public Collection getElements() { + return elements; + } + } + + class Source { + private final Collection elements; + + public Source(Collection elements) { + this.elements = elements; + } + + public Collection getElements() { + return elements; + } + } + + class Element { + private final String name; + + public Element(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3159/Issue3159Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3159/Issue3159Test.java new file mode 100644 index 0000000000..77feba151c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3159/Issue3159Test.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3159; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3159") +@WithClasses(Issue3159Mapper.class) +class Issue3159Test { + + @ProcessorTest + void shouldUseDefaultExpressionForCollection() { + Issue3159Mapper.Target target = Issue3159Mapper.INSTANCE.map( new Issue3159Mapper.Source( null ) ); + + assertThat( target.getElements() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Issue3163Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Issue3163Mapper.java new file mode 100644 index 0000000000..bd44a9d386 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Issue3163Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3163; + +import java.util.Optional; + +import org.mapstruct.Mapper; + +@Mapper +public interface Issue3163Mapper { + + Target map(Source value); + + Target.Nested map(Source.Nested value); + + default Optional wrapAsOptional(T value) { + return Optional.ofNullable( value ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Issue3163Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Issue3163Test.java new file mode 100644 index 0000000000..5c16a707f3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Issue3163Test.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3163; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@WithClasses({ + Issue3163Mapper.class, + Source.class, + Target.class +}) +class Issue3163Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Source.java new file mode 100644 index 0000000000..8f5a57f1bf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Source.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3163; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final Nested nested; + + public Source(Nested nested) { + this.nested = nested; + } + + public Nested getNested() { + return nested; + } + + public static class Nested { + private final String value; + + public Nested(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Target.java new file mode 100644 index 0000000000..301a281d2d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3163/Target.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3163; + +import java.util.Optional; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private Nested nested; + + public Optional getNested() { + return Optional.ofNullable( nested ); + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + public final void setNested(Optional nested) { + this.nested = nested.orElse( null ); + } + + public static class Nested { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3165/Issue3165Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3165/Issue3165Mapper.java new file mode 100644 index 0000000000..b6d5fc1ed7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3165/Issue3165Mapper.java @@ -0,0 +1,65 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3165; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue3165Mapper { + + Issue3165Mapper INSTANCE = Mappers.getMapper( Issue3165Mapper.class ); + + Target toTarget(Source source); + + class Source { + private String[] pets; + private Iterable cats; + + public Source(String[] pets, Iterable cats) { + this.pets = pets; + this.cats = cats; + } + + public String[] getPets() { + return pets; + } + + public Iterable getCats() { + return cats; + } + } + + class Target { + private List pets; + private List cats; + + Target() { + this.pets = new ArrayList<>(); + this.cats = new ArrayList<>(); + } + + public List getPets() { + return pets; + } + + public void addPet(String pet) { + pets.add( pet ); + } + + public List getCats() { + return cats; + } + + public void addCat(String cat) { + cats.add( cat ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3165/Issue3165MapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3165/Issue3165MapperTest.java new file mode 100644 index 0000000000..4fb9e0ab3a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3165/Issue3165MapperTest.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3165; + +import java.util.Arrays; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + Issue3165Mapper.class +}) +@IssueKey("3165") +class Issue3165MapperTest { + + @ProcessorTest + void supportsAdderWhenMappingArrayAndIterableToCollection() { + Issue3165Mapper.Source src = new Issue3165Mapper.Source( + new String[] { "cat", "dog", "mouse" }, + Arrays.asList( "ivy", "flu", "freya" ) + ); + Issue3165Mapper.Target target = Issue3165Mapper.INSTANCE.toTarget( src ); + assertThat( target.getPets() ).containsExactly( "cat", "dog", "mouse" ); + assertThat( target.getCats() ).containsExactly( "ivy", "flu", "freya" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3238/ErroneousIssue3238Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3238/ErroneousIssue3238Mapper.java new file mode 100644 index 0000000000..fd0d4672a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3238/ErroneousIssue3238Mapper.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3238; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface ErroneousIssue3238Mapper { + + @Mapping(target = ".", ignore = true) + Target map(Source source); + + class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3238/Issue3238Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3238/Issue3238Test.java new file mode 100644 index 0000000000..6648495a70 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3238/Issue3238Test.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3238; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +@WithClasses(ErroneousIssue3238Mapper.class) +@IssueKey("3238") +class Issue3238Test { + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = @Diagnostic( type = ErroneousIssue3238Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 14, + message = "Using @Mapping( target = \".\", ignore = true ) is not allowed." + + " You need to use @BeanMapping( ignoreByDefault = true ) if you would like to ignore" + + " all non explicitly mapped target properties." + ) + ) + void shouldGenerateValidCompileError() { + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3248/Issue3248Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3248/Issue3248Mapper.java new file mode 100644 index 0000000000..e0cbba40f7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3248/Issue3248Mapper.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3248; + +import org.mapstruct.BeanMapping; +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface Issue3248Mapper { + + @BeanMapping(ignoreUnmappedSourceProperties = "otherValue") + Target map(Source source); + + @InheritConfiguration + Target secondMap(Source source); + + class Target { + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public String getOtherValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3248/Issue3248Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3248/Issue3248Test.java new file mode 100644 index 0000000000..ad8cf2e499 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3248/Issue3248Test.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3248; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3248") +@WithClasses({ + Issue3248Mapper.class +}) +class Issue3248Test { + + @ProcessorTest + void shouldCompileCode() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Entity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Entity.java new file mode 100644 index 0000000000..cfd038b03c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Entity.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +public class Entity { + String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Issue3296Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Issue3296Test.java new file mode 100644 index 0000000000..9bd28d333a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Issue3296Test.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Ben Zegveld + */ +@IssueKey( "3296" ) +@WithClasses( { Entity.class, Payload.class } ) +public class Issue3296Test { + + @ProcessorTest + @WithClasses( { MapperExtendingConfig.class, MapperConfigWithPayloadArgument.class } ) + public void shouldNotRaiseErrorForDefaultAfterMappingMethodImplementation() { + Payload payload = new Payload(); + payload.setName( "original" ); + + Entity entity = Mappers.getMapper( MapperExtendingConfig.class ).toEntity( payload ); + + assertThat( entity.getName() ).isEqualTo( "AfterMapping called" ); + } + + @ProcessorTest + @WithClasses( { MapperNotExtendingConfig.class, MapperConfigWithoutPayloadArgument.class } ) + public void shouldNotRaiseErrorRequiringArgumentsForDefaultMethods() { + Payload payload = new Payload(); + payload.setName( "original" ); + + Entity entity = Mappers.getMapper( MapperNotExtendingConfig.class ).toEntity( payload ); + + assertThat( entity.getName() ).isEqualTo( "original" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperConfigWithPayloadArgument.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperConfigWithPayloadArgument.java new file mode 100644 index 0000000000..69826aa10e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperConfigWithPayloadArgument.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +import org.mapstruct.AfterMapping; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingTarget; + +@MapperConfig +public interface MapperConfigWithPayloadArgument { + + @AfterMapping + default void afterMapping(@MappingTarget Entity entity, Payload unused) { + staticMethod( entity ); + } + + static void staticMethod(Entity entity) { + entity.setName( "AfterMapping called" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperConfigWithoutPayloadArgument.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperConfigWithoutPayloadArgument.java new file mode 100644 index 0000000000..36cc046d12 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperConfigWithoutPayloadArgument.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +import org.mapstruct.AfterMapping; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingTarget; + +@MapperConfig +public interface MapperConfigWithoutPayloadArgument { + + @AfterMapping + default void afterMapping(@MappingTarget Entity entity) { + staticMethod( entity ); + } + + static void staticMethod(Entity entity) { + entity.setName( "AfterMapping called" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperExtendingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperExtendingConfig.java new file mode 100644 index 0000000000..157bd051cb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperExtendingConfig.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +import org.mapstruct.Mapper; + +@Mapper( config = MapperConfigWithPayloadArgument.class ) +public interface MapperExtendingConfig extends MapperConfigWithPayloadArgument { + Entity toEntity(Payload payload); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperNotExtendingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperNotExtendingConfig.java new file mode 100644 index 0000000000..2ceb18c253 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/MapperNotExtendingConfig.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +import org.mapstruct.Mapper; + +@Mapper( config = MapperConfigWithoutPayloadArgument.class ) +public interface MapperNotExtendingConfig { + Entity toEntity(Payload payload); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Payload.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Payload.java new file mode 100644 index 0000000000..2502e5e4a2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3296/Payload.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3296; + +public class Payload { + + String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3310/Issue3310Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3310/Issue3310Mapper.java new file mode 100644 index 0000000000..2975a5de8a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3310/Issue3310Mapper.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3310; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface Issue3310Mapper { + + Issue3310Mapper INSTANCE = Mappers.getMapper( Issue3310Mapper.class ); + + Target map(Source source); + + abstract class BaseClass { + + private List items; + + public List getItems() { + return items; + } + + public void setItems(List items) { + throw new UnsupportedOperationException( "adder should be used instead" ); + } + + public void addItem(T item) { + if ( items == null ) { + items = new ArrayList<>(); + } + items.add( item ); + } + } + + class Target extends BaseClass { + + } + + class Source { + + private final List items; + + public Source(List items) { + this.items = items; + } + + public List getItems() { + return items; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3310/Issue3310Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3310/Issue3310Test.java new file mode 100644 index 0000000000..a00526985f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3310/Issue3310Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3310; + +import java.util.Collections; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3310") +@WithClasses(Issue3310Mapper.class) +class Issue3310Test { + + @ProcessorTest + void shouldUseAdderWithGenericBaseClass() { + Issue3310Mapper.Source source = new Issue3310Mapper.Source( Collections.singletonList( "test" ) ); + Issue3310Mapper.Target target = Issue3310Mapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getItems() ).containsExactly( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3317/Issue3317Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3317/Issue3317Mapper.java new file mode 100644 index 0000000000..33a40b1dfb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3317/Issue3317Mapper.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3317; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3317Mapper { + + Issue3317Mapper INSTANCE = Mappers.getMapper( Issue3317Mapper.class ); + + Target map(int id, long value); + + class Target { + + private final int id; + private final long value; + + public Target(int id, long value) { + this.id = id; + this.value = value; + } + + public int getId() { + return id; + } + + public long getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3317/Issue3317Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3317/Issue3317Test.java new file mode 100644 index 0000000000..218a1f8979 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3317/Issue3317Test.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3317; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3317") +@WithClasses(Issue3317Mapper.class) +class Issue3317Test { + + @ProcessorTest + void shouldGenerateValidCode() { + Issue3317Mapper.Target target = Issue3317Mapper.INSTANCE.map( 10, 42L ); + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( 10 ); + assertThat( target.getValue() ).isEqualTo( 42L ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Issue3331Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Issue3331Mapper.java new file mode 100644 index 0000000000..3011479c65 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Issue3331Mapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3331; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) +public interface Issue3331Mapper { + + Issue3331Mapper INSTANCE = Mappers.getMapper( Issue3331Mapper.class ); + + @SubclassMapping(source = Vehicle.Car.class, target = VehicleDto.Car.class) + @SubclassMapping(source = Vehicle.Motorbike.class, target = VehicleDto.Motorbike.class) + @Mapping(target = "name", constant = "noname") + VehicleDto map(Vehicle vehicle); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Issue3331Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Issue3331Test.java new file mode 100644 index 0000000000..3871868226 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Issue3331Test.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3331; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3331") +@WithClasses({ + Issue3331Mapper.class, + Vehicle.class, + VehicleDto.class, +}) +class Issue3331Test { + + @ProcessorTest + void shouldCorrectCompileAndThrowExceptionOnRuntime() { + VehicleDto target = Issue3331Mapper.INSTANCE.map( new Vehicle.Car( "Test car", 4 ) ); + + assertThat( target.getName() ).isEqualTo( "noname" ); + assertThat( target ) + .isInstanceOfSatisfying( VehicleDto.Car.class, car -> { + assertThat( car.getNumOfDoors() ).isEqualTo( 4 ); + } ); + + target = Issue3331Mapper.INSTANCE.map( new Vehicle.Motorbike( "Test bike", true ) ); + + assertThat( target.getName() ).isEqualTo( "noname" ); + assertThat( target ) + .isInstanceOfSatisfying( VehicleDto.Motorbike.class, bike -> { + assertThat( bike.isAllowedForMinor() ).isTrue(); + } ); + + assertThatThrownBy( () -> Issue3331Mapper.INSTANCE.map( new Vehicle.Truck( "Test truck", 3 ) ) ) + .isInstanceOf( IllegalArgumentException.class ) + .hasMessage( "Not all subclasses are supported for this mapping. Missing for " + Vehicle.Truck.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Vehicle.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Vehicle.java new file mode 100644 index 0000000000..3b68a3acc4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/Vehicle.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3331; + +/** + * @author Filip Hrisafov + */ +public abstract class Vehicle { + + private final String name; + + protected Vehicle(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static class Car extends Vehicle { + + private final int numOfDoors; + + public Car(String name, int numOfDoors) { + super( name ); + this.numOfDoors = numOfDoors; + } + + public int getNumOfDoors() { + return numOfDoors; + } + } + + public static class Motorbike extends Vehicle { + + private final boolean allowedForMinor; + + public Motorbike(String name, boolean allowedForMinor) { + super( name ); + this.allowedForMinor = allowedForMinor; + } + + public boolean isAllowedForMinor() { + return allowedForMinor; + } + } + + public static class Truck extends Vehicle { + + private final int numOfAxis; + + public Truck(String name, int numOfAxis) { + super( name ); + this.numOfAxis = numOfAxis; + } + + public int getNumOfAxis() { + return numOfAxis; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/VehicleDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/VehicleDto.java new file mode 100644 index 0000000000..8c2ef13dd2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3331/VehicleDto.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3331; + +/** + * @author Filip Hrisafov + */ +public abstract class VehicleDto { + + private final String name; + + protected VehicleDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static class Car extends VehicleDto { + + private final int numOfDoors; + + public Car(String name, int numOfDoors) { + super( name ); + this.numOfDoors = numOfDoors; + } + + public int getNumOfDoors() { + return numOfDoors; + } + } + + public static class Motorbike extends VehicleDto { + + private final boolean allowedForMinor; + + public Motorbike(String name, boolean allowedForMinor) { + super( name ); + this.allowedForMinor = allowedForMinor; + } + + public boolean isAllowedForMinor() { + return allowedForMinor; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Issue3360Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Issue3360Mapper.java new file mode 100644 index 0000000000..812d885489 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Issue3360Mapper.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3360; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper( + subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION, + unmappedTargetPolicy = ReportingPolicy.ERROR, + unmappedSourcePolicy = ReportingPolicy.ERROR +) +public interface Issue3360Mapper { + + Issue3360Mapper INSTANCE = Mappers.getMapper( Issue3360Mapper.class ); + + @SubclassMapping(target = VehicleDto.Car.class, source = Vehicle.Car.class) + VehicleDto map(Vehicle vehicle); + + @Mapping(target = "model", source = "modelName") + @BeanMapping(ignoreUnmappedSourceProperties = "computedName") + VehicleDto.Car map(Vehicle.Car car); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Issue3360Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Issue3360Test.java new file mode 100644 index 0000000000..307c2b265a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Issue3360Test.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3360; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3360") +@WithClasses({ + Issue3360Mapper.class, + Vehicle.class, + VehicleDto.class, +}) +class Issue3360Test { + + @ProcessorTest + void shouldCompileWithoutErrorsAndWarnings() { + + Vehicle vehicle = new Vehicle.Car( "Test", "car", 4 ); + + VehicleDto target = Issue3360Mapper.INSTANCE.map( vehicle ); + + assertThat( target.getName() ).isEqualTo( "Test" ); + assertThat( target.getModel() ).isEqualTo( "car" ); + assertThat( target ).isInstanceOfSatisfying( VehicleDto.Car.class, car -> { + assertThat( car.getNumOfDoors() ).isEqualTo( 4 ); + } ); + + assertThatThrownBy( () -> Issue3360Mapper.INSTANCE.map( new Vehicle.Motorbike( "Test", "bike" ) ) ) + .isInstanceOf( IllegalArgumentException.class ) + .hasMessage( "Not all subclasses are supported for this mapping. Missing for " + Vehicle.Motorbike.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Vehicle.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Vehicle.java new file mode 100644 index 0000000000..0cc2011bc9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/Vehicle.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3360; + +/** + * @author Filip Hrisafov + */ +public abstract class Vehicle { + + private final String name; + private final String modelName; + + protected Vehicle(String name, String modelName) { + this.name = name; + this.modelName = modelName; + } + + public String getName() { + return name; + } + + public String getModelName() { + return modelName; + } + + public String getComputedName() { + return null; + } + + public static class Car extends Vehicle { + + private final int numOfDoors; + + public Car(String name, String modelName, int numOfDoors) { + super( name, modelName ); + this.numOfDoors = numOfDoors; + } + + public int getNumOfDoors() { + return numOfDoors; + } + } + + public static class Motorbike extends Vehicle { + + public Motorbike(String name, String modelName) { + super( name, modelName ); + } + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/VehicleDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/VehicleDto.java new file mode 100644 index 0000000000..fc93a2fcae --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3360/VehicleDto.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3360; + +/** + * @author Filip Hrisafov + */ +public abstract class VehicleDto { + + private String name; + private String model; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getModel() { + return model; + } + + public void setModel(String model) { + this.model = model; + } + + public static class Car extends VehicleDto { + + private int numOfDoors; + + public int getNumOfDoors() { + return numOfDoors; + } + + public void setNumOfDoors(int numOfDoors) { + this.numOfDoors = numOfDoors; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3361/Issue3361Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3361/Issue3361Mapper.java new file mode 100644 index 0000000000..a556b63306 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3361/Issue3361Mapper.java @@ -0,0 +1,80 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3361; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public abstract class Issue3361Mapper { + + public static final Issue3361Mapper INSTANCE = Mappers.getMapper( Issue3361Mapper.class ); + + @Mapping(target = "someAttribute", source = "source.attribute") + @Mapping(target = "otherAttribute", source = "otherSource.anotherAttribute") + public abstract Target mapFromSource(Source source, OtherSource otherSource); + + @InheritConfiguration(name = "mapFromSource") + @Mapping(target = "otherAttribute", source = "source", qualifiedByName = "otherMapping") + public abstract Target mapInherited(Source source, OtherSource otherSource); + + @Named("otherMapping") + protected Long otherMapping(Source source) { + return source.getAttribute() != null ? 1L : 0L; + } + + public static class Target { + private String someAttribute; + private Long otherAttribute; + + public String getSomeAttribute() { + return someAttribute; + } + + public Target setSomeAttribute(String someAttribute) { + this.someAttribute = someAttribute; + return this; + } + + public Long getOtherAttribute() { + return otherAttribute; + } + + public Target setOtherAttribute(Long otherAttribute) { + this.otherAttribute = otherAttribute; + return this; + } + } + + public static class Source { + private final String attribute; + + public Source(String attribute) { + this.attribute = attribute; + } + + public String getAttribute() { + return attribute; + } + } + + public static class OtherSource { + + private final Long anotherAttribute; + + public OtherSource(Long anotherAttribute) { + this.anotherAttribute = anotherAttribute; + } + + public Long getAnotherAttribute() { + return anotherAttribute; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3361/Issue3361Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3361/Issue3361Test.java new file mode 100644 index 0000000000..3fa16ec1ae --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3361/Issue3361Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3361; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3361") +@WithClasses(Issue3361Mapper.class) +class Issue3361Test { + + @ProcessorTest + void multiSourceShouldInherit() { + Issue3361Mapper.Source source = new Issue3361Mapper.Source( "Test" ); + Issue3361Mapper.OtherSource otherSource = new Issue3361Mapper.OtherSource( 10L ); + + Issue3361Mapper.Target target = Issue3361Mapper.INSTANCE.mapFromSource( source, otherSource ); + assertThat( target.getSomeAttribute() ).isEqualTo( "Test" ); + assertThat( target.getOtherAttribute() ).isEqualTo( 10L ); + + target = Issue3361Mapper.INSTANCE.mapInherited( source, otherSource ); + assertThat( target.getSomeAttribute() ).isEqualTo( "Test" ); + assertThat( target.getOtherAttribute() ).isEqualTo( 1L ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/Issue3370BuilderProvider.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/Issue3370BuilderProvider.java new file mode 100644 index 0000000000..55a3f783c3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/Issue3370BuilderProvider.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3370; + +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; + +import org.mapstruct.ap.spi.BuilderInfo; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesBuilderProvider; + +public class Issue3370BuilderProvider extends ImmutablesBuilderProvider implements BuilderProvider { + + @Override + protected BuilderInfo findBuilderInfoForImmutables(TypeElement typeElement) { + Name name = typeElement.getQualifiedName(); + if ( name.toString().endsWith( ".Item" ) ) { + return super.findBuilderInfo( asImmutableElement( typeElement ) ); + } + return super.findBuilderInfo( typeElement ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/Issue3370Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/Issue3370Test.java new file mode 100644 index 0000000000..0389de5b46 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/Issue3370Test.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3370; + +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.ap.spi.AccessorNamingStrategy; +import org.mapstruct.ap.spi.BuilderProvider; +import org.mapstruct.ap.spi.ImmutablesAccessorNamingStrategy; +import org.mapstruct.ap.test.bugs._3370.domain.ImmutableItem; +import org.mapstruct.ap.test.bugs._3370.domain.Item; +import org.mapstruct.ap.test.bugs._3370.dto.ItemDTO; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithServiceImplementation; +import org.mapstruct.ap.testutil.WithServiceImplementations; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + ItemMapper.class, + Item.class, + ImmutableItem.class, + ItemDTO.class, +}) +@IssueKey("3370") +@WithServiceImplementations({ + @WithServiceImplementation(provides = BuilderProvider.class, value = Issue3370BuilderProvider.class), + @WithServiceImplementation(provides = AccessorNamingStrategy.class, + value = ImmutablesAccessorNamingStrategy.class), +}) +public class Issue3370Test { + + @ProcessorTest + public void shouldUseBuilderOfImmutableSuperClass() { + + Map attributesMap = new HashMap<>(); + attributesMap.put( "a", "b" ); + attributesMap.put( "c", "d" ); + + ItemDTO item = new ItemDTO( "test", attributesMap ); + + Item target = ItemMapper.INSTANCE.map( item ); + + assertThat( target ).isNotNull(); + assertThat( target.getId() ).isEqualTo( "test" ); + assertThat( target.getAttributes() ).isEqualTo( attributesMap ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/ItemMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/ItemMapper.java new file mode 100644 index 0000000000..5583e191b3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/ItemMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3370; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.bugs._3370.domain.Item; +import org.mapstruct.ap.test.bugs._3370.dto.ItemDTO; +import org.mapstruct.factory.Mappers; + +@Mapper +public abstract class ItemMapper { + + public static final ItemMapper INSTANCE = Mappers.getMapper( ItemMapper.class ); + + public abstract Item map(ItemDTO itemDTO); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/domain/ImmutableItem.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/domain/ImmutableItem.java new file mode 100644 index 0000000000..fabae2f0d0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/domain/ImmutableItem.java @@ -0,0 +1,316 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3370.domain; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +/** + * Immutable implementation of {@link Item}. + *

      + * Use the builder to create immutable instances: + * {@code new Item.Builder()}. + */ +@SuppressWarnings("all") +public final class ImmutableItem extends Item { + private final String id; + private final Map attributes; + + private ImmutableItem(String id, Map attributes) { + this.id = id; + this.attributes = attributes; + } + + /** + * @return The value of the {@code id} attribute + */ + @Override + public String getId() { + return id; + } + + /** + * @return The value of the {@code attributes} attribute + */ + @Override + public Map getAttributes() { + return attributes; + } + + /** + * Copy the current immutable object by setting a value for the {@link Item#getId() id} attribute. + * An equals check used to prevent copying of the same value by returning {@code this}. + * + * @param id A new value for id + * @return A modified copy of the {@code this} object + */ + public final ImmutableItem withId(String id) { + if ( this.id.equals( id ) ) { + return this; + } + String newValue = Objects.requireNonNull( id, "id" ); + return new ImmutableItem( newValue, this.attributes ); + } + + /** + * Copy the current immutable object by replacing the {@link Item#getAttributes() attributes} map with the specified map. + * Nulls are not permitted as keys or values. + * A shallow reference equality check is used to prevent copying of the same value by returning {@code this}. + * + * @param attributes The entries to be added to the attributes map + * @return A modified copy of {@code this} object + */ + public final ImmutableItem withAttributes(Map attributes) { + if ( this.attributes == attributes ) { + return this; + } + Map newValue = createUnmodifiableMap( true, false, attributes ); + return new ImmutableItem( this.id, newValue ); + } + + /** + * This instance is equal to all instances of {@code ImmutableItem} that have equal attribute values. + * + * @return {@code true} if {@code this} is equal to {@code another} instance + */ + @Override + public boolean equals(Object another) { + if ( this == another ) { + return true; + } + return another instanceof ImmutableItem + && equalTo( (ImmutableItem) another ); + } + + private boolean equalTo(ImmutableItem another) { + return id.equals( another.id ) + && attributes.equals( another.attributes ); + } + + /** + * Computes a hash code from attributes: {@code id}, {@code attributes}. + * + * @return hashCode value + */ + @Override + public int hashCode() { + int h = 31; + h = h * 17 + id.hashCode(); + h = h * 17 + attributes.hashCode(); + return h; + } + + /** + * Prints the immutable value {@code Item} with attribute values. + * + * @return A string representation of the value + */ + @Override + public String toString() { + return "Item{" + + "id=" + id + + ", attributes=" + attributes + + "}"; + } + + /** + * Creates an immutable copy of a {@link Item} value. + * Uses accessors to get values to initialize the new immutable instance. + * If an instance is already immutable, it is returned as is. + * + * @param instance The instance to copy + * @return A copied immutable Item instance + */ + public static ImmutableItem copyOf(Item instance) { + if ( instance instanceof ImmutableItem ) { + return (ImmutableItem) instance; + } + return new Item.Builder() + .from( instance ) + .build(); + } + + /** + * Builds instances of type {@link ImmutableItem ImmutableItem}. + * Initialize attributes and then invoke the {@link #build()} method to create an + * immutable instance. + *

      {@code Builder} is not thread-safe and generally should not be stored in a field or collection, + * but instead used immediately to create instances. + */ + public static class Builder { + private static final long INIT_BIT_ID = 0x1L; + private long initBits = 0x1L; + + private String id; + private Map attributes = new LinkedHashMap(); + + /** + * Creates a builder for {@link ImmutableItem ImmutableItem} instances. + */ + public Builder() { + if ( !( this instanceof Item.Builder ) ) { + throw new UnsupportedOperationException( "Use: new Item.Builder()" ); + } + } + + /** + * Fill a builder with attribute values from the provided {@code Item} instance. + * Regular attribute values will be replaced with those from the given instance. + * Absent optional values will not replace present values. + * Collection elements and entries will be added, not replaced. + * + * @param instance The instance from which to copy values + * @return {@code this} builder for use in a chained invocation + */ + public final Item.Builder from(Item instance) { + Objects.requireNonNull( instance, "instance" ); + id( instance.getId() ); + putAllAttributes( instance.getAttributes() ); + return (Item.Builder) this; + } + + /** + * Initializes the value for the {@link Item#getId() id} attribute. + * + * @param id The value for id + * @return {@code this} builder for use in a chained invocation + */ + public final Item.Builder id(String id) { + this.id = Objects.requireNonNull( id, "id" ); + initBits &= ~INIT_BIT_ID; + return (Item.Builder) this; + } + + /** + * Put one entry to the {@link Item#getAttributes() attributes} map. + * + * @param key The key in the attributes map + * @param value The associated value in the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final Item.Builder putAttributes(String key, String value) { + this.attributes.put( + Objects.requireNonNull( key, "attributes key" ), + Objects.requireNonNull( value, "attributes value" ) + ); + return (Item.Builder) this; + } + + /** + * Put one entry to the {@link Item#getAttributes() attributes} map. Nulls are not permitted + * + * @param entry The key and value entry + * @return {@code this} builder for use in a chained invocation + */ + public final Item.Builder putAttributes(Map.Entry entry) { + String k = entry.getKey(); + String v = entry.getValue(); + this.attributes.put( + Objects.requireNonNull( k, "attributes key" ), + Objects.requireNonNull( v, "attributes value" ) + ); + return (Item.Builder) this; + } + + /** + * Sets or replaces all mappings from the specified map as entries for the {@link Item#getAttributes() attributes} map. Nulls are not permitted + * + * @param attributes The entries that will be added to the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final Item.Builder attributes(Map attributes) { + this.attributes.clear(); + return putAllAttributes( attributes ); + } + + /** + * Put all mappings from the specified map as entries to {@link Item#getAttributes() attributes} map. Nulls are not permitted + * + * @param attributes The entries that will be added to the attributes map + * @return {@code this} builder for use in a chained invocation + */ + public final Item.Builder putAllAttributes(Map attributes) { + for ( Map.Entry entry : attributes.entrySet() ) { + String k = entry.getKey(); + String v = entry.getValue(); + this.attributes.put( + Objects.requireNonNull( k, "attributes key" ), + Objects.requireNonNull( v, "attributes value" ) + ); + } + return (Item.Builder) this; + } + + /** + * Builds a new {@link ImmutableItem ImmutableItem}. + * + * @return An immutable instance of Item + * @throws java.lang.IllegalStateException if any required attributes are missing + */ + public ImmutableItem build() { + if ( initBits != 0 ) { + throw new IllegalStateException( formatRequiredAttributesMessage() ); + } + return new ImmutableItem( id, createUnmodifiableMap( false, false, attributes ) ); + } + + private String formatRequiredAttributesMessage() { + List attributes = new ArrayList<>(); + if ( ( initBits & INIT_BIT_ID ) != 0 ) { + attributes.add( "id" ); + } + return "Cannot build Item, some of required attributes are not set " + attributes; + } + } + + private static Map createUnmodifiableMap(boolean checkNulls, boolean skipNulls, + Map map) { + switch ( map.size() ) { + case 0: + return Collections.emptyMap(); + case 1: { + Map.Entry e = map.entrySet().iterator().next(); + K k = e.getKey(); + V v = e.getValue(); + if ( checkNulls ) { + Objects.requireNonNull( k, "key" ); + Objects.requireNonNull( v, "value" ); + } + if ( skipNulls && ( k == null || v == null ) ) { + return Collections.emptyMap(); + } + return Collections.singletonMap( k, v ); + } + default: { + Map linkedMap = new LinkedHashMap( map.size() ); + if ( skipNulls || checkNulls ) { + for ( Map.Entry e : map.entrySet() ) { + K k = e.getKey(); + V v = e.getValue(); + if ( skipNulls ) { + if ( k == null || v == null ) { + continue; + } + } + else if ( checkNulls ) { + Objects.requireNonNull( k, "key" ); + Objects.requireNonNull( v, "value" ); + } + linkedMap.put( k, v ); + } + } + else { + linkedMap.putAll( map ); + } + return Collections.unmodifiableMap( linkedMap ); + } + } + } +} \ No newline at end of file diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/domain/Item.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/domain/Item.java new file mode 100644 index 0000000000..a78c3bc007 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/domain/Item.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3370.domain; + +import java.util.Collections; +import java.util.Map; + +public abstract class Item { + + public abstract String getId(); + + public abstract Map getAttributes(); + + public static Item.Builder builder() { + return new Item.Builder(); + } + + public static class Builder extends ImmutableItem.Builder { + + public ImmutableItem.Builder addSomeData(String key, String data) { + return super.attributes( Collections.singletonMap( key, data ) ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/dto/ItemDTO.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/dto/ItemDTO.java new file mode 100644 index 0000000000..70dba87fe4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3370/dto/ItemDTO.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3370.dto; + +import java.util.Map; + +public class ItemDTO { + private final String id; + private final Map attributes; + + public ItemDTO(String id, Map attributes) { + this.id = id; + this.attributes = attributes; + } + + public String getId() { + return id; + } + + public Map getAttributes() { + return attributes; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java new file mode 100644 index 0000000000..784e47b8e7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Erroneous3413Mapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3413; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Muhammad Usama + */ +@Mapper +public interface Erroneous3413Mapper { + Erroneous3413Mapper INSTANCE = Mappers.getMapper( Erroneous3413Mapper.class ); + + @Mapping(target = "", expression = "", conditionQualifiedByName = "") + ToPOJO map(FromPOJO fromPOJO); + + class FromPOJO { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class ToPOJO { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java new file mode 100644 index 0000000000..f98ed9cdbd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3413/Issue3413Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3413; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Muhammad Usama + */ +@IssueKey("3413") +public class Issue3413Test { + @ProcessorTest + @WithClasses(Erroneous3413Mapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 19, + message = "Expression and condition qualified by name are both defined in @Mapping, " + + "either define an expression or a condition qualified by name." + ) + } + ) + void errorExpectedBecauseExpressionAndConditionQualifiedByNameCannotCoExists() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3462/Issue3462Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3462/Issue3462Mapper.java new file mode 100644 index 0000000000..1bf87672c6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3462/Issue3462Mapper.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3462; + +import java.util.List; +import java.util.stream.Stream; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3462Mapper { + + Issue3462Mapper INSTANCE = Mappers.getMapper( Issue3462Mapper.class ); + + Target map(Source source); + + class Source { + private final List values; + + public Source(List values) { + this.values = values; + } + + public List getValues() { + return values; + } + + public Stream getValuesStream() { + return values != null ? values.stream() : Stream.empty(); + } + } + + class Target { + private List values; + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } + + public Stream getValuesStream() { + return values != null ? values.stream() : Stream.empty(); + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3462/Issue3462Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3462/Issue3462Test.java new file mode 100644 index 0000000000..16be4f441e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3462/Issue3462Test.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3462; + +import java.util.Arrays; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3462") +@WithClasses(Issue3462Mapper.class) +class Issue3462Test { + + @ProcessorTest + void shouldNotTreatStreamGettersAsAlternativeSetter() { + + Issue3462Mapper.Source source = new Issue3462Mapper.Source( Arrays.asList( "first", "second" ) ); + Issue3462Mapper.Target target = Issue3462Mapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getValues() ).containsExactly( "first", "second" ); + assertThat( target.getValuesStream() ).containsExactly( "first", "second" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/EntityBuilder.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/EntityBuilder.java new file mode 100644 index 0000000000..6b0b71993e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/EntityBuilder.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3463; + +/** + * @author Filip Hrisafov + */ +public interface EntityBuilder { + + T build(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Issue3463Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Issue3463Mapper.java new file mode 100644 index 0000000000..37ead3dfdf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Issue3463Mapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3463; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3463Mapper { + + Issue3463Mapper INSTANCE = Mappers.getMapper( Issue3463Mapper.class ); + + Person map(PersonDto dto); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Issue3463Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Issue3463Test.java new file mode 100644 index 0000000000..e6cfc3ece7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Issue3463Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3463; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3463") +@WithClasses({ + EntityBuilder.class, + Issue3463Mapper.class, + Person.class, + PersonDto.class +}) +class Issue3463Test { + + @ProcessorTest + void shouldUseInterfaceBuildMethod() { + Person person = Issue3463Mapper.INSTANCE.map( new PersonDto( "Tester" ) ); + + assertThat( person ).isNotNull(); + assertThat( person.getName() ).isEqualTo( "Tester" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Person.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Person.java new file mode 100644 index 0000000000..977d619474 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/Person.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3463; + +/** + * @author Filip Hrisafov + */ +public class Person { + + private final String name; + + private Person(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static Builder builder() { + return new BuilderImpl(); + } + + public interface Builder extends EntityBuilder { + + Builder name(String name); + } + + private static final class BuilderImpl implements Builder { + + private String name; + + private BuilderImpl() { + } + + @Override + public Builder name(String name) { + this.name = name; + return this; + } + + @Override + public Person build() { + return new Person( this.name ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/PersonDto.java new file mode 100644 index 0000000000..447e4813cc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3463/PersonDto.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3463; + +/** + * @author Filip Hrisafov + */ +public class PersonDto { + private final String name; + + public PersonDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3485/ErroneousIssue3485Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3485/ErroneousIssue3485Mapper.java new file mode 100644 index 0000000000..dc1558907c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3485/ErroneousIssue3485Mapper.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3485; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author hduelme + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface ErroneousIssue3485Mapper { + + ErroneousIssue3485Mapper INSTANCE = Mappers.getMapper( ErroneousIssue3485Mapper.class ); + + class Target { + private final String value; + + public Target( String value ) { + this.value = value; + } + + public String getValue() { + return value; + } + + } + + @Mapping(target = ".") + Target targetFromExpression(String s); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3485/Issue3485Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3485/Issue3485Test.java new file mode 100644 index 0000000000..964de36ec8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3485/Issue3485Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3485; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author hduelme + */ +@IssueKey("3485") +public class Issue3485Test { + + @ProcessorTest + @WithClasses(ErroneousIssue3485Mapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousIssue3485Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 34, + message = "Using @Mapping( target = \".\") requires a source property. Expression or " + + "constant cannot be used as a source.") + }) + void thisMappingWithoutSource() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3561/Issue3561Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3561/Issue3561Mapper.java new file mode 100644 index 0000000000..fd1137137b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3561/Issue3561Mapper.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3561; + +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue3561Mapper { + + Issue3561Mapper INSTANCE = Mappers.getMapper( Issue3561Mapper.class ); + + @Mapping(target = "value", conditionQualifiedByName = "shouldMapValue") + Target map(Source source, @Context boolean shouldMapValue); + + @Condition + @Named("shouldMapValue") + default boolean shouldMapValue(@Context boolean shouldMapValue) { + return shouldMapValue; + } + + class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Source { + + private String value; + private boolean valueInitialized; + + public String getValue() { + if ( valueInitialized ) { + return value; + } + + throw new IllegalStateException( "value is not initialized" ); + } + + public void setValue(String value) { + this.valueInitialized = true; + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3561/Issue3561Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3561/Issue3561Test.java new file mode 100644 index 0000000000..7cd0c26694 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3561/Issue3561Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3561; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3561Mapper.class) +@IssueKey("3561") +class Issue3561Test { + + @ProcessorTest + void shouldCorrectlyUseConditionWithContext() { + + Issue3561Mapper.Source source = new Issue3561Mapper.Source(); + + assertThatThrownBy( () -> Issue3561Mapper.INSTANCE.map( source, true ) ) + .isInstanceOf( IllegalStateException.class ) + .hasMessage( "value is not initialized" ); + + Issue3561Mapper.Target target = Issue3561Mapper.INSTANCE.map( source, false ); + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3565/Issue3565Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3565/Issue3565Mapper.java new file mode 100644 index 0000000000..b86e667e56 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3565/Issue3565Mapper.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3565; + +import java.util.Optional; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3565Mapper { + + Issue3565Mapper INSTANCE = Mappers.getMapper( Issue3565Mapper.class ); + + default T mapFromOptional(Optional value) { + return value.orElse( (T) null ); + } + + @Condition + default boolean isOptionalPresent(Optional value) { + return value.isPresent(); + } + + Target map(Source source); + + class Source { + + private final Boolean condition; + + public Source(Boolean condition) { + this.condition = condition; + } + + public Optional getCondition() { + return Optional.ofNullable( this.condition ); + } + } + + class Target { + private String condition; + + public Optional getCondition() { + return Optional.ofNullable( this.condition ); + } + + public void setCondition(String condition) { + this.condition = condition; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3565/Issue3565Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3565/Issue3565Test.java new file mode 100644 index 0000000000..c4cd028d45 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3565/Issue3565Test.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3565; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3565Mapper.class) +@IssueKey("3565") +class Issue3565Test { + + @ProcessorTest + void shouldGenerateValidCode() { + Issue3565Mapper.Target target = Issue3565Mapper.INSTANCE.map( new Issue3565Mapper.Source( null ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getCondition() ).isEmpty(); + + target = Issue3565Mapper.INSTANCE.map( new Issue3565Mapper.Source( false ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getCondition() ).hasValue( "false" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/Bean.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/Bean.java new file mode 100644 index 0000000000..7da423c906 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/Bean.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import java.util.List; + +public class Bean { + private List beans; + private String value; + + public Bean() { + } + + public Bean(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getBeans() { + return beans; + } + + public void setBeans(List beans) { + this.beans = beans; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/BeanDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/BeanDto.java new file mode 100644 index 0000000000..00e70ff228 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/BeanDto.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import java.util.List; + +public class BeanDto { + + private List beans; + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public List getBeans() { + return beans; + } + + public void setBeans(List beans) { + this.beans = beans; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/BeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/BeanMapper.java new file mode 100644 index 0000000000..eeb54b4710 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/BeanMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface BeanMapper { + + BeanMapper INSTANCE = Mappers.getMapper( BeanMapper.class ); + + @Mapping(source = "beans", target = "beans") + BeanDto map(Bean bean, @MappingTarget BeanDto beanDto); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBean.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBean.java new file mode 100644 index 0000000000..b0e68ecfcf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBean.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import java.util.Map; +import java.util.stream.Stream; + +public class ContainerBean { + + private String value; + private Map beanMap; + private Stream beanStream; + + public ContainerBean() { + } + + public ContainerBean(String value) { + this.value = value; + } + + public Map getBeanMap() { + return beanMap; + } + + public void setBeanMap(Map beanMap) { + this.beanMap = beanMap; + } + + public Stream getBeanStream() { + return beanStream; + } + + public void setBeanStream(Stream beanStream) { + this.beanStream = beanStream; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBeanDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBeanDto.java new file mode 100644 index 0000000000..86bb0193ac --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBeanDto.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import java.util.Map; +import java.util.stream.Stream; + +public class ContainerBeanDto { + + private String value; + private Map beanMap; + private Stream beanStream; + + public Map getBeanMap() { + return beanMap; + } + + public void setBeanMap(Map beanMap) { + this.beanMap = beanMap; + } + + public Stream getBeanStream() { + return beanStream; + } + + public void setBeanStream(Stream beanStream) { + this.beanStream = beanStream; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBeanMapper.java new file mode 100644 index 0000000000..0da338aadf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/ContainerBeanMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ContainerBeanMapper { + + ContainerBeanMapper INSTANCE = Mappers.getMapper( ContainerBeanMapper.class ); + + @Mapping(source = "beanMap", target = "beanMap") + @Mapping(source = "beanStream", target = "beanStream") + ContainerBeanDto mapWithMapMapping(ContainerBean containerBean, @MappingTarget ContainerBeanDto containerBeanDto); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/Issue3591Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/Issue3591Test.java new file mode 100644 index 0000000000..15bb191ffc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3591/Issue3591Test.java @@ -0,0 +1,79 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3591; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3591") +class Issue3591Test { + + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + BeanDto.class, + Bean.class, + BeanMapper.class + }) + void mapNestedBeansWithMappingAnnotation() { + Bean bean = new Bean( "parent" ); + Bean child = new Bean( "child" ); + bean.setBeans( Collections.singletonList( child ) ); + + BeanDto beanDto = BeanMapper.INSTANCE.map( bean, new BeanDto() ); + + assertThat( beanDto ).isNotNull(); + assertThat( beanDto.getValue() ).isEqualTo( "parent" ); + assertThat( beanDto.getBeans() ) + .extracting( BeanDto::getValue ) + .containsExactly( "child" ); + } + + @ProcessorTest + @WithClasses({ + ContainerBean.class, + ContainerBeanDto.class, + ContainerBeanMapper.class, + }) + void shouldMapNestedMapAndStream() { + generatedSource.addComparisonToFixtureFor( ContainerBeanMapper.class ); + + ContainerBean containerBean = new ContainerBean( "parent" ); + Map beanMap = new HashMap<>(); + beanMap.put( "child", new ContainerBean( "mapChild" ) ); + containerBean.setBeanMap( beanMap ); + + Stream streamChild = Stream.of( new ContainerBean( "streamChild" ) ); + containerBean.setBeanStream( streamChild ); + + ContainerBeanDto dto = ContainerBeanMapper.INSTANCE.mapWithMapMapping( containerBean, new ContainerBeanDto() ); + + assertThat( dto ).isNotNull(); + + assertThat( dto.getBeanMap() ) + .extractingByKey( "child" ) + .extracting( ContainerBeanDto::getValue ) + .isEqualTo( "mapChild" ); + + assertThat( dto.getBeanStream() ) + .singleElement() + .extracting( ContainerBeanDto::getValue ) + .isEqualTo( "streamChild" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3601/Issue3601Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3601/Issue3601Mapper.java new file mode 100644 index 0000000000..851e353de7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3601/Issue3601Mapper.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3601; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourceParameterCondition; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3601Mapper { + + Issue3601Mapper INSTANCE = Mappers.getMapper( Issue3601Mapper.class ); + + @Mapping(target = "currentId", source = "source.uuid") + @Mapping(target = "targetIds", source = "sourceIds") + Target map(Source source, List sourceIds); + + @SourceParameterCondition + default boolean isNotEmpty(List elements) { + return elements != null && !elements.isEmpty(); + } + + class Source { + private final String uuid; + + public Source(String uuid) { + this.uuid = uuid; + } + + public String getUuid() { + return uuid; + } + } + + class Target { + //CHECKSTYLE:OFF + public String currentId; + public List targetIds; + //CHECKSTYLE:ON + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3601/Issue3601Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3601/Issue3601Test.java new file mode 100644 index 0000000000..b9b68fb583 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3601/Issue3601Test.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3601; + +import java.util.Collections; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3601") +class Issue3601Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses( Issue3601Mapper.class ) + void shouldUseSourceParameterPresenceCheckCorrectly() { + Issue3601Mapper.Target target = Issue3601Mapper.INSTANCE.map( + new Issue3601Mapper.Source( "test1" ), + Collections.emptyList() + ); + + assertThat( target ).isNotNull(); + assertThat( target.currentId ).isEqualTo( "test1" ); + assertThat( target.targetIds ).isNull(); + + target = Issue3601Mapper.INSTANCE.map( + null, + Collections.emptyList() + ); + + assertThat( target ).isNull(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3609/Issue3609Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3609/Issue3609Mapper.java new file mode 100644 index 0000000000..41b1e2aefa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3609/Issue3609Mapper.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3609; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.SubclassMapping; + +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public abstract class Issue3609Mapper { + + @SubclassMapping(source = CarDto.class, target = Car.class) + @BeanMapping(ignoreUnmappedSourceProperties = "id") + public abstract Vehicle toVehicle(VehicleDto vehicle); + + //CHECKSTYLE:OFF + public static class Vehicle { + public int price; + } + + public static class Car extends Vehicle { + public int seats; + + public Car(int price, int seats) { + this.price = price; + this.seats = seats; + } + } + + public static class VehicleDto { + public int id; + public int price; + } + + public static class CarDto extends VehicleDto { + public int seats; + } + //CHECKSTYLE:ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3609/Issue3609Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3609/Issue3609Test.java new file mode 100644 index 0000000000..8a57a1357f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3609/Issue3609Test.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3609; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Roman Obolonskyii + */ +@IssueKey("3609") +@WithClasses(Issue3609Mapper.class) +public class Issue3609Test { + + @ProcessorTest + void shouldCompileWithoutErrors() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Bar.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Bar.java new file mode 100644 index 0000000000..3ac8b595ee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Bar.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3652; + +public class Bar { + + private int secret; + private int doesNotExistInFoo; + + public int getSecret() { + return secret; + } + + public void setSecret(int secret) { + this.secret = secret; + } + + public int getDoesNotExistInFoo() { + return doesNotExistInFoo; + } + + public void setDoesNotExistInFoo(int doesNotExistInFoo) { + this.doesNotExistInFoo = doesNotExistInFoo; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Foo.java new file mode 100644 index 0000000000..02b5b6e8b0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Foo.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3652; + +public class Foo { + + private int secret; + + public int getSecret() { + return secret; + } + + public void setSecret(int secret) { + this.secret = secret; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/FooBarConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/FooBarConfig.java new file mode 100644 index 0000000000..3cf19dfbfb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/FooBarConfig.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3652; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.MappingInheritanceStrategy; + +@MapperConfig(mappingInheritanceStrategy = MappingInheritanceStrategy.AUTO_INHERIT_ALL_FROM_CONFIG) +public interface FooBarConfig { + + @Mapping(target = "doesNotExistInFoo", ignore = true) + @Mapping(target = "secret", ignore = true) + Bar toBar(Foo foo); + + @InheritInverseConfiguration(name = "toBar") + Foo toFoo(Bar bar); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/FooBarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/FooBarMapper.java new file mode 100644 index 0000000000..d58be74f1e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/FooBarMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3652; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper(config = FooBarConfig.class) +public interface FooBarMapper { + + FooBarMapper INSTANCE = Mappers.getMapper( FooBarMapper.class ); + + Bar toBar(Foo foo); + + Foo toFoo(Bar bar); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Issue3652Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Issue3652Test.java new file mode 100644 index 0000000000..aa8a64ada8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3652/Issue3652Test.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3652; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3652") +public class Issue3652Test { + + @WithClasses({ + Bar.class, + Foo.class, + FooBarConfig.class, + FooBarMapper.class, + }) + @ProcessorTest + void ignoreMappingsWithoutSourceShouldBeInvertible() { + Bar bar = new Bar(); + bar.setSecret( 123 ); + bar.setDoesNotExistInFoo( 6 ); + + Foo foo = FooBarMapper.INSTANCE.toFoo( bar ); + + assertThat( foo.getSecret() ).isEqualTo( 0 ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Issue3667Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Issue3667Mapper.java new file mode 100644 index 0000000000..d4f2dff0af --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Issue3667Mapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3667; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue3667Mapper { + + Issue3667Mapper INSTANCE = Mappers.getMapper( Issue3667Mapper.class ); + + @Mapping(target = "nested.value", source = "nested.nested1.value") + Target mapFirst(Source source); + + @Mapping(target = "nested.value", source = "nested.nested2.value") + Target mapSecond(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Issue3667Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Issue3667Test.java new file mode 100644 index 0000000000..1e91de00d7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Issue3667Test.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3667; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3667") +@WithClasses({ + Issue3667Mapper.class, + Source.class, + Target.class +}) +class Issue3667Test { + + @ProcessorTest + void shouldCorrectlyMapNestedProperty() { + Source source = new Source( + new Source.Nested( + new Source.NestedNested( "value1" ), + new Source.NestedNested( "value2" ) + ) + ); + + Target target1 = Issue3667Mapper.INSTANCE.mapFirst( source ); + Target target2 = Issue3667Mapper.INSTANCE.mapSecond( source ); + + assertThat( target1 ).isNotNull(); + assertThat( target1.getNested() ).isNotNull(); + assertThat( target1.getNested().getValue() ).isEqualTo( "value1" ); + + assertThat( target2 ).isNotNull(); + assertThat( target2.getNested() ).isNotNull(); + assertThat( target2.getNested().getValue() ).isEqualTo( "value2" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Source.java new file mode 100644 index 0000000000..ede78edf0d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Source.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3667; + +public class Source { + + private final Nested nested; + + public Source(Nested nested) { + this.nested = nested; + } + + public Nested getNested() { + return nested; + } + + public static class Nested { + + private final NestedNested nested1; + private final NestedNested nested2; + + public Nested(NestedNested nested1, NestedNested nested2) { + this.nested1 = nested1; + this.nested2 = nested2; + } + + public NestedNested getNested1() { + return nested1; + } + + public NestedNested getNested2() { + return nested2; + } + } + + public static class NestedNested { + + private final String value; + + public NestedNested(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Target.java new file mode 100644 index 0000000000..e0c8d23296 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3667/Target.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3667; + +public class Target { + + private Nested nested; + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + + public static class Nested { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Child.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Child.java new file mode 100644 index 0000000000..3c10c4d470 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Child.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class Child { + + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public static class ChildA extends Child { } + + public static class ChildB extends Child { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildDto.java new file mode 100644 index 0000000000..458cc57a9a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildDto.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class ChildDto { + + private Long id; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public static class ChildDtoA extends ChildDto { } + + public static class ChildDtoB extends ChildDto { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildMapper.java new file mode 100644 index 0000000000..c381a99fcd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ChildMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +import org.mapstruct.Mapper; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; + +@Mapper(subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) +public interface ChildMapper { + + @SubclassMapping(target = Child.ChildA.class, source = ChildDto.ChildDtoA.class) + @SubclassMapping(target = Child.ChildB.class, source = ChildDto.ChildDtoB.class) + Child toEntity(ChildDto childDto); + + @SubclassMapping(target = ChildDto.ChildDtoA.class, source = Child.ChildA.class) + @SubclassMapping(target = ChildDto.ChildDtoB.class, source = Child.ChildB.class) + ChildDto toDto(Child child); + + Child.ChildA toEntity(ChildDto.ChildDtoA childDto); + + ChildDto.ChildDtoA toDto(Child.ChildA child); + + Child.ChildB toEntity(ChildDto.ChildDtoB childDto); + + ChildDto.ChildDtoB toDto(Child.ChildB child); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Issue3668Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Issue3668Test.java new file mode 100644 index 0000000000..a35ac70dce --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Issue3668Test.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3668") +@WithClasses({ + Child.class, + ChildDto.class, + ChildMapper.class, + Parent.class, + ParentDto.class, + ParentMapper.class, +}) +class Issue3668Test { + + @ProcessorTest + void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Parent.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Parent.java new file mode 100644 index 0000000000..900a7fa68b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/Parent.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class Parent { + + private Long id; + + private T child; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public T getChild() { + return child; + } + + public void setChild(T child) { + this.child = child; + } + + public static class ParentA extends Parent { } + + public static class ParentB extends Parent { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentDto.java new file mode 100644 index 0000000000..f4736ceef0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentDto.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +public abstract class ParentDto { + + private Long id; + + private T child; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public T getChild() { + return child; + } + + public void setChild(T child) { + this.child = child; + } + + public static class ParentDtoA extends ParentDto { } + + public static class ParentDtoB extends ParentDto { } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentMapper.java new file mode 100644 index 0000000000..484ddbc930 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3668/ParentMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3668; + +import org.mapstruct.Mapper; +import org.mapstruct.SubclassExhaustiveStrategy; +import org.mapstruct.SubclassMapping; + +@Mapper(uses = { ChildMapper.class }, subclassExhaustiveStrategy = SubclassExhaustiveStrategy.RUNTIME_EXCEPTION) +public interface ParentMapper { + + @SubclassMapping(target = Parent.ParentA.class, source = ParentDto.ParentDtoA.class) + @SubclassMapping(target = Parent.ParentB.class, source = ParentDto.ParentDtoB.class) + Parent toEntity(ParentDto parentDto); + + @SubclassMapping(target = ParentDto.ParentDtoA.class, source = Parent.ParentA.class) + @SubclassMapping(target = ParentDto.ParentDtoB.class, source = Parent.ParentB.class) + ParentDto toDto(Parent parent); + + Parent.ParentA toEntity(ParentDto.ParentDtoA parentDto); + + ParentDto.ParentDtoA toDto(Parent.ParentA parent); + + Parent.ParentB toEntity(ParentDto.ParentDtoB parentDto); + + ParentDto.ParentDtoB toDto(Parent.ParentB parent); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3670/Issue3670Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3670/Issue3670Mapper.java new file mode 100644 index 0000000000..a014a7d52d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3670/Issue3670Mapper.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3670; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3670Mapper { + + @Mapping(target = "name", source = ".", qualifiedByName = "nestedName") + Target map(Source source); + + @InheritInverseConfiguration + @Mapping(target = "nested.nestedName", source = "name") + Source map(Target target); + + @Named("nestedName") + default String mapNestedName(Source source) { + if ( source == null ) { + return null; + } + + Nested nested = source.getNested(); + + return nested != null ? nested.getNestedName() : null; + } + + class Target { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + class Nested { + private String nestedName; + + public String getNestedName() { + return nestedName; + } + + public void setNestedName(String nestedName) { + this.nestedName = nestedName; + } + } + + class Source { + + private Nested nested; + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3670/Issue3670Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3670/Issue3670Test.java new file mode 100644 index 0000000000..fc3929b685 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3670/Issue3670Test.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3670; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3670") +@WithClasses(Issue3670Mapper.class) +class Issue3670Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Animal.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Animal.java new file mode 100644 index 0000000000..9fe97e0e79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Animal.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +public class Animal { + + private AnimalDetails details; + + public AnimalDetails getDetails() { + return details; + } + + public void setDetails(AnimalDetails details) { + this.details = details; + } + + public enum Type { + CAT, + DOG + } + + public static class AnimalDetails { + private Type type; + private String name; + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Cat.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Cat.java new file mode 100644 index 0000000000..63e5391690 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Cat.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +public class Cat { + + private final Details details; + + public Cat(Details details) { + this.details = details; + } + + public Details getDetails() { + return details; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Details.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Details.java new file mode 100644 index 0000000000..8526793015 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Details.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +public class Details { + + private final String name; + + public Details(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Dog.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Dog.java new file mode 100644 index 0000000000..a021a5d579 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Dog.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +public class Dog { + + private final Details details; + + public Dog(Details details) { + this.details = details; + } + + public Details getDetails() { + return details; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673ConstantMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673ConstantMapper.java new file mode 100644 index 0000000000..d74a954f9f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673ConstantMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue3673ConstantMapper { + + Issue3673ConstantMapper INSTANCE = Mappers.getMapper( Issue3673ConstantMapper.class ); + + @Mapping(target = "details.name", source = "details.name") + @Mapping(target = "details.type", constant = "DOG") + Animal map(Dog dog); + + @Mapping(target = "details.name", source = "details.name") + @Mapping(target = "details.type", constant = "CAT") + Animal map(Cat cat); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673ExpressionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673ExpressionMapper.java new file mode 100644 index 0000000000..3aca966807 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673ExpressionMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue3673ExpressionMapper { + + Issue3673ExpressionMapper INSTANCE = Mappers.getMapper( Issue3673ExpressionMapper.class ); + + @Mapping(target = "details.name", source = "details.name") + @Mapping(target = "details.type", expression = "java(Animal.Type.DOG)") + Animal map(Dog dog); + + @Mapping(target = "details.name", source = "details.name") + @Mapping(target = "details.type", expression = "java(Animal.Type.CAT)") + Animal map(Cat cat); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673Test.java new file mode 100644 index 0000000000..2d796b4670 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3673/Issue3673Test.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3673; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3673") +@WithClasses({ + Cat.class, + Dog.class, + Details.class, + Animal.class +}) +class Issue3673Test { + + @ProcessorTest + @WithClasses(Issue3673ConstantMapper.class) + void shouldCorrectlyMapNestedPropertyConstant() { + + Animal cat = Issue3673ConstantMapper.INSTANCE.map( + new Cat( new Details( "cat" ) ) + ); + + Animal dog = Issue3673ConstantMapper.INSTANCE.map( + new Dog( new Details( "dog" ) ) + ); + + assertThat( cat ).isNotNull(); + assertThat( cat.getDetails() ).isNotNull(); + assertThat( cat.getDetails().getName() ).isEqualTo( "cat" ); + assertThat( cat.getDetails().getType() ).isEqualTo( Animal.Type.CAT ); + + assertThat( dog ).isNotNull(); + assertThat( dog.getDetails() ).isNotNull(); + assertThat( dog.getDetails().getName() ).isEqualTo( "dog" ); + assertThat( dog.getDetails().getType() ).isEqualTo( Animal.Type.DOG ); + } + + @ProcessorTest + @WithClasses(Issue3673ExpressionMapper.class) + void shouldCorrectlyMapNestedPropertyExpression() { + + Animal cat = Issue3673ExpressionMapper.INSTANCE.map( + new Cat( new Details( "cat" ) ) + ); + + Animal dog = Issue3673ExpressionMapper.INSTANCE.map( + new Dog( new Details( "dog" ) ) + ); + + assertThat( cat ).isNotNull(); + assertThat( cat.getDetails() ).isNotNull(); + assertThat( cat.getDetails().getName() ).isEqualTo( "cat" ); + assertThat( cat.getDetails().getType() ).isEqualTo( Animal.Type.CAT ); + + assertThat( dog ).isNotNull(); + assertThat( dog.getDetails() ).isNotNull(); + assertThat( dog.getDetails().getName() ).isEqualTo( "dog" ); + assertThat( dog.getDetails().getType() ).isEqualTo( Animal.Type.DOG ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3678/Issue3678Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3678/Issue3678Mapper.java new file mode 100644 index 0000000000..374fbf931a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3678/Issue3678Mapper.java @@ -0,0 +1,128 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3678; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue3678Mapper { + + Issue3678Mapper INSTANCE = Mappers.getMapper( Issue3678Mapper.class ); + + @Mapping(target = "name", source = "sourceA.name") + @Mapping(target = "description", source = "sourceB.description") + Target map(SourceA sourceA, SourceB sourceB, @Context MappingContext context); + + @Mapping(target = "description", constant = "some description") + Target map(SourceA sourceA, @Context MappingContext context); + + class MappingContext { + + private final List invokedMethods = new ArrayList<>(); + + @BeforeMapping + public void beforeMappingSourceA(SourceA sourceA) { + invokedMethods.add( "beforeMappingSourceA" ); + } + + @AfterMapping + public void afterMappingSourceB(SourceA sourceA) { + invokedMethods.add( "afterMappingSourceA" ); + } + + @BeforeMapping + public void beforeMappingSourceB(SourceB sourceB) { + invokedMethods.add( "beforeMappingSourceB" ); + } + + @AfterMapping + public void afterMappingSourceB(SourceB sourceB) { + invokedMethods.add( "afterMappingSourceB" ); + } + + public List getInvokedMethods() { + return invokedMethods; + } + } + + class SourceA { + + private final String name; + + public SourceA(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class SourceB { + + private final String description; + + public SourceB(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + } + + final class Target { + + private final String name; + private final String description; + + private Target(String name, String description) { + this.name = name; + this.description = description; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + + private String name; + private String description; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder description(String description) { + this.description = description; + return this; + } + + public Target build() { + return new Target( this.name, this.description ); + } + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3678/Issue3678Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3678/Issue3678Test.java new file mode 100644 index 0000000000..25e7e21622 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3678/Issue3678Test.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3678; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3678") +@WithClasses(Issue3678Mapper.class) +public class Issue3678Test { + + @ProcessorTest + void beforeAndAfterMappingOnlyCalledOnceForTwoSources() { + + Issue3678Mapper.MappingContext mappingContext = new Issue3678Mapper.MappingContext(); + Issue3678Mapper.SourceA sourceA = new Issue3678Mapper.SourceA( "name" ); + Issue3678Mapper.SourceB sourceB = new Issue3678Mapper.SourceB( "description" ); + Issue3678Mapper.INSTANCE.map( sourceA, sourceB, mappingContext ); + + assertThat( mappingContext.getInvokedMethods() ) + .containsExactly( + "beforeMappingSourceA", + "beforeMappingSourceB", + "afterMappingSourceA", + "afterMappingSourceB" + ); + } + + @ProcessorTest + void beforeAndAfterMappingOnlyCalledOnceForSingleSource() { + + Issue3678Mapper.MappingContext mappingContext = new Issue3678Mapper.MappingContext(); + Issue3678Mapper.SourceA sourceA = new Issue3678Mapper.SourceA( "name" ); + Issue3678Mapper.INSTANCE.map( sourceA, mappingContext ); + + assertThat( mappingContext.getInvokedMethods() ) + .containsExactly( + "beforeMappingSourceA", + "afterMappingSourceA" + ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/Issue3703Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/Issue3703Mapper.java new file mode 100644 index 0000000000..287e7655fb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/Issue3703Mapper.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3703; + +import org.mapstruct.AfterMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.ap.test.bugs._3703.dto.Contact; + +@Mapper +public interface Issue3703Mapper { + + Contact map(org.mapstruct.ap.test.bugs._3703.entity.Contact contact); + + org.mapstruct.ap.test.bugs._3703.entity.Contact map(Contact contact); + + @AfterMapping + default void afterMapping(@MappingTarget Contact target, org.mapstruct.ap.test.bugs._3703.entity.Contact contact) { + } + + @AfterMapping + default void afterMapping(@MappingTarget Contact.Builder targetBuilder, + org.mapstruct.ap.test.bugs._3703.entity.Contact contact) { + } + + @AfterMapping + default void afterMapping(@MappingTarget org.mapstruct.ap.test.bugs._3703.entity.Contact target, Contact contact) { + } + + @AfterMapping + default void afterMapping(@MappingTarget org.mapstruct.ap.test.bugs._3703.entity.Contact.Builder targetBuilder, + Contact contact) { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/Issue3703Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/Issue3703Test.java new file mode 100644 index 0000000000..ac5cae3959 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/Issue3703Test.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3703; + +import org.mapstruct.ap.test.bugs._3703.dto.Contact; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@IssueKey("3703") +@WithClasses({ + Contact.class, + org.mapstruct.ap.test.bugs._3703.entity.Contact.class, + Issue3703Mapper.class +}) +public class Issue3703Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/dto/Contact.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/dto/Contact.java new file mode 100644 index 0000000000..a949864791 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/dto/Contact.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3703.dto; + +public class Contact { + + private final String name; + + private Contact(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private String name; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Contact build() { + return new Contact( name ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/entity/Contact.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/entity/Contact.java new file mode 100644 index 0000000000..31fde373fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3703/entity/Contact.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3703.entity; + +public class Contact { + + private final String name; + + private Contact(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static Builder newBuilder() { + return new Builder(); + } + + public static class Builder { + + private String name; + + public Builder name(String name) { + this.name = name; + return this; + } + + public Contact build() { + return new Contact( name ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/BaseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/BaseMapper.java new file mode 100644 index 0000000000..e2a04fe336 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/BaseMapper.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3711; + +import org.mapstruct.Context; + +interface BaseMapper { + E toEntity(T s, @Context JpaContext ctx); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/Issue3711Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/Issue3711Test.java new file mode 100644 index 0000000000..7b141e9e14 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/Issue3711Test.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3711; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + ParentEntity.class, + ParentDto.class, + JpaContext.class, + SourceTargetMapper.class, + BaseMapper.class, +}) +@IssueKey("3711") +class Issue3711Test { + @ProcessorTest + void shouldGenerateContextMethod() { + JpaContext jpaContext = new JpaContext<>(); + SourceTargetMapper.INSTANCE.toEntity( new ParentDto(), jpaContext ); + + assertThat( jpaContext.getInvokedMethods() ) + .containsExactly( "beforeMapping", "afterMapping" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/JpaContext.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/JpaContext.java new file mode 100644 index 0000000000..b21bf639d7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/JpaContext.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3711; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.MappingTarget; + +public class JpaContext { + private final List invokedMethods = new ArrayList<>(); + + @BeforeMapping + void beforeMapping(@MappingTarget T parentEntity) { + invokedMethods.add( "beforeMapping" ); + } + + @AfterMapping + void afterMapping(@MappingTarget T parentEntity) { + invokedMethods.add( "afterMapping" ); + } + + public List getInvokedMethods() { + return invokedMethods; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/ParentDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/ParentDto.java new file mode 100644 index 0000000000..664d6e58ab --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/ParentDto.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3711; + +public class ParentDto { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/ParentEntity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/ParentEntity.java new file mode 100644 index 0000000000..aaefa949fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/ParentEntity.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3711; + +public class ParentEntity { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/SourceTargetMapper.java new file mode 100644 index 0000000000..b09333fd56 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3711/SourceTargetMapper.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3711; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SourceTargetMapper extends BaseMapper { + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + ParentEntity toDTO(ParentDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Branch.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Branch.java index 5177c46687..2f3165b32f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Branch.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Branch.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._373; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/BranchLocation.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/BranchLocation.java index 43efd95a0a..b5d83e015e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/BranchLocation.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/BranchLocation.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._373; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Country.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Country.java index 912c1a3e02..9d6b827626 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Country.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Country.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._373; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Mapper.java index 66999ad905..ac64cd7db1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._373; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Test.java index bcafe22503..91c01ac7c2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/Issue373Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._373; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/373. @@ -30,10 +15,9 @@ * @author Sjaak Derksen */ @IssueKey( "373" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue373Test { - @Test + @ProcessorTest @WithClasses( { Issue373Mapper.class, Branch.class, BranchLocation.class, Country.class, ResultDto.class } ) public void shouldForgeCorrectEntityBranchLocationCountry() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/ResultDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/ResultDto.java index a37839371e..d3799efbed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/ResultDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_373/ResultDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._373; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3732/Issue3732Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3732/Issue3732Mapper.java new file mode 100644 index 0000000000..79b13aa8ce --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3732/Issue3732Mapper.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3732; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3732Mapper { + + Target map(Source source); + + Source map(Target source); + + class Source { + private LocalDateTime value; + + public LocalDateTime getValue() { + return value; + } + + public void setValue(LocalDateTime value) { + this.value = value; + } + } + + class Target { + + private LocalDate value; + + public LocalDate getValue() { + return value; + } + + public void setValue(LocalDate value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3732/Issue3732Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3732/Issue3732Test.java new file mode 100644 index 0000000000..9dbd9c0bb8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3732/Issue3732Test.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3732; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3732") +@WithClasses({ Issue3732Mapper.class }) +class Issue3732Test { + + @ProcessorTest + void shouldGenerateCorrectMapper() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Mapper.java index db3c985181..b12bbd5e07 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._374; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Test.java index 82d27b5b93..2bc6d6a170 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374Test.java @@ -1,35 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._374; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/306. @@ -37,10 +22,9 @@ * @author Sjaak Derksen */ @IssueKey( "306" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue374Test { - @Test + @ProcessorTest @WithClasses( { Issue374Mapper.class, Source.class, Target.class } ) public void shouldMapExistingTargetToDefault() { @@ -51,40 +35,41 @@ public void shouldMapExistingTargetToDefault() { assertThat( result.getConstant() ).isEqualTo( "test" ); } - @Test + @ProcessorTest @WithClasses( { Issue374Mapper.class, Source.class, Target.class } ) public void shouldMapExistingTargetWithConstantToDefault() { Target target2 = new Target(); Target result2 = Issue374Mapper.INSTANCE.map2( null, target2 ); - assertThat( result2 ).isNull(); + assertThat( result2 ).isNotNull(); + assertThat( result2 ).isEqualTo( target2 ); assertThat( target2.getTest() ).isNull(); assertThat( target2.getConstant() ).isNull(); } - @Test + @ProcessorTest @WithClasses( { Issue374Mapper.class, Source.class, Target.class } ) public void shouldMapExistingIterableTargetToDefault() { - List targetList = new ArrayList(); + List targetList = new ArrayList<>(); targetList.add( "test" ); List resultList = Issue374Mapper.INSTANCE.mapIterable( null, targetList ); assertThat( resultList ).isEqualTo( targetList ); assertThat( targetList ).isEmpty(); } - @Test + @ProcessorTest @WithClasses( { Issue374Mapper.class, Source.class, Target.class } ) public void shouldMapExistingMapTargetToDefault() { - Map targetMap = new HashMap(); + Map targetMap = new HashMap<>(); targetMap.put( 5, "test" ); Map resultMap = Issue374Mapper.INSTANCE.mapMap( null, targetMap ); assertThat( resultMap ).isEmpty(); assertThat( resultMap ).isEqualTo( resultMap ); } - @Test + @ProcessorTest @WithClasses( { Issue374VoidMapper.class, Source.class, Target.class } ) public void shouldMapExistingTargetVoidReturnToDefault() { @@ -94,21 +79,21 @@ public void shouldMapExistingTargetVoidReturnToDefault() { assertThat( target.getConstant() ).isEqualTo( "test" ); } - @Test + @ProcessorTest @WithClasses( { Issue374VoidMapper.class, Source.class, Target.class } ) public void shouldMapExistingIterableTargetVoidReturnToDefault() { - List targetList = new ArrayList(); + List targetList = new ArrayList<>(); targetList.add( "test" ); Issue374VoidMapper.INSTANCE.mapIterable( null, targetList ); assertThat( targetList ).isEmpty(); } - @Test + @ProcessorTest @WithClasses( { Issue374VoidMapper.class, Source.class, Target.class } ) public void shouldMapExistingMapTargetVoidReturnToDefault() { - Map targetMap = new HashMap(); + Map targetMap = new HashMap<>(); targetMap.put( 5, "test" ); Issue374VoidMapper.INSTANCE.mapMap( null, targetMap ); assertThat( targetMap ).isEmpty(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374VoidMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374VoidMapper.java index bff99efe6a..6fa27a806c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374VoidMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Issue374VoidMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._374; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Source.java index e57c3737f0..349fd4a1e7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._374; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Target.java index cdd53f038f..ab87548921 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_374/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._374; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3747/Issue3747Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3747/Issue3747Mapper.java new file mode 100644 index 0000000000..04addc43f3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3747/Issue3747Mapper.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3747; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValueMappingStrategy; + +/** + * @author Filip Hrisafov + */ +@Mapper(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) +public interface Issue3747Mapper { + + Target map(Source source); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3747/Issue3747Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3747/Issue3747Test.java new file mode 100644 index 0000000000..57650e4dc0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3747/Issue3747Test.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3747; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3747") +@WithClasses(Issue3747Mapper.class) +class Issue3747Test { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + void shouldNotGenerateObsoleteCode() { + generatedSource.addComparisonToFixtureFor( Issue3747Mapper.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Case.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Case.java index 025fdc5a90..2eb9e1aaa5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Case.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Case.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Int.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Int.java index 324cd4d8a6..0006257cfa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Int.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Int.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Mapper.java index 2e790f30ca..acc76e04c9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Test.java index 723d74b6a5..3cbd2fcad1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Issue375Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._375; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/375. @@ -30,10 +15,9 @@ * @author Sjaak Derksen */ @IssueKey( "375" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue375Test { - @Test + @ProcessorTest @WithClasses( { Issue375Mapper.class, Source.class, Target.class, Int.class, Case.class } ) public void shouldForgeNewMappings() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Source.java index f02aefb4d6..2418fb7fdf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Source.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._375; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Target.java index c6d3abe850..80a86f2cb2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_375/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._375; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3786/ErroneousByteArrayMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3786/ErroneousByteArrayMapper.java new file mode 100644 index 0000000000..abf84f8228 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3786/ErroneousByteArrayMapper.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3786; + +import org.mapstruct.Mapper; + +@Mapper +public interface ErroneousByteArrayMapper { + byte[] map( String something ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3786/Issue3786Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3786/Issue3786Test.java new file mode 100644 index 0000000000..bd71392c30 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3786/Issue3786Test.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3786; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Ben Zegveld + */ +@IssueKey( "3786" ) +public class Issue3786Test { + + @WithClasses( ErroneousByteArrayMapper.class ) + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + type = ErroneousByteArrayMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 12, + message = "Can't generate mapping method from non-iterable type to array." + ) + } + ) + void byteArrayReturnTypeShouldGiveInaccessibleContructorError() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3806/Issue3806Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3806/Issue3806Mapper.java new file mode 100644 index 0000000000..89f325dfbb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3806/Issue3806Mapper.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3806; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface Issue3806Mapper { + + Issue3806Mapper INSTANCE = Mappers.getMapper( Issue3806Mapper.class ); + + void update(@MappingTarget Target target, Target source); + + class Target { + + private final Collection authors; + private final Map booksByAuthor; + + protected Collection books; + protected Map booksByPublisher; + + public Target(Collection authors, Map booksByAuthor) { + this.authors = authors != null ? new ArrayList<>( authors ) : null; + this.booksByAuthor = booksByAuthor != null ? new HashMap<>( booksByAuthor ) : null; + } + + public Collection getAuthors() { + return authors; + } + + public Map getBooksByAuthor() { + return booksByAuthor; + } + + public Collection getBooks() { + return books; + } + + public void setBooks(Collection books) { + this.books = books; + } + + public Map getBooksByPublisher() { + return booksByPublisher; + } + + public void setBooksByPublisher(Map booksByPublisher) { + this.booksByPublisher = booksByPublisher; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3806/Issue3806Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3806/Issue3806Test.java new file mode 100644 index 0000000000..1df3318c22 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3806/Issue3806Test.java @@ -0,0 +1,86 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3806; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +@WithClasses(Issue3806Mapper.class) +@IssueKey("3806") +class Issue3806Test { + + @ProcessorTest + void shouldNotClearGetterOnlyCollectionsInUpdateMapping() { + Map booksByAuthor = new HashMap<>(); + booksByAuthor.put( "author1", "book1" ); + booksByAuthor.put( "author2", "book2" ); + List authors = new ArrayList<>(); + authors.add( "author1" ); + authors.add( "author2" ); + + List books = new ArrayList<>(); + books.add( "book1" ); + books.add( "book2" ); + Map booksByPublisher = new HashMap<>(); + booksByPublisher.put( "publisher1", "book1" ); + booksByPublisher.put( "publisher2", "book2" ); + Issue3806Mapper.Target target = new Issue3806Mapper.Target( authors, booksByAuthor ); + target.setBooks( books ); + target.setBooksByPublisher( booksByPublisher ); + + Issue3806Mapper.Target source = new Issue3806Mapper.Target( null, null ); + Issue3806Mapper.INSTANCE.update( target, source ); + + assertThat( target.getAuthors() ).containsExactly( "author1", "author2" ); + assertThat( target.getBooksByAuthor() ) + .containsOnly( + entry( "author1", "book1" ), + entry( "author2", "book2" ) + ); + + assertThat( target.getBooks() ).containsExactly( "book1", "book2" ); + assertThat( target.getBooksByPublisher() ) + .containsOnly( + entry( "publisher1", "book1" ), + entry( "publisher2", "book2" ) + ); + + booksByAuthor = new HashMap<>(); + booksByAuthor.put( "author3", "book3" ); + authors = new ArrayList<>(); + authors.add( "author3" ); + + books = new ArrayList<>(); + books.add( "book3" ); + booksByPublisher = new HashMap<>(); + booksByPublisher.put( "publisher3", "book3" ); + source = new Issue3806Mapper.Target( authors, booksByAuthor ); + source.setBooks( books ); + source.setBooksByPublisher( booksByPublisher ); + Issue3806Mapper.INSTANCE.update( target, source ); + + assertThat( target.getAuthors() ).containsExactly( "author3" ); + assertThat( target.getBooksByAuthor() ) + .containsOnly( + entry( "author3", "book3" ) + ); + + assertThat( target.getBooks() ).containsExactly( "book3" ); + assertThat( target.getBooksByPublisher() ) + .containsOnly( + entry( "publisher3", "book3" ) + ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3807/Issue3807Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3807/Issue3807Mapper.java new file mode 100644 index 0000000000..83ee1f32bd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3807/Issue3807Mapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3807; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface Issue3807Mapper { + Issue3807Mapper INSTANCE = Mappers.getMapper( Issue3807Mapper.class ); + + TargetWithoutSetter mapNoSetter(Source target); + + NormalTarget mapNormalSource(Source target); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + //CHECKSTYLE:OFF + class TargetWithoutSetter { + public T value; + } + //CHECKSTYLE:ON + + class NormalTarget { + private T value; + + public T getValue() { + return value; + } + + public void setValue(T value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3807/Issue3807Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3807/Issue3807Test.java new file mode 100644 index 0000000000..db82472f98 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3807/Issue3807Test.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3807; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses(Issue3807Mapper.class) +@IssueKey("3807") +class Issue3807Test { + + @ProcessorTest + void fieldAndSetterShouldWorkWithGeneric() { + Issue3807Mapper.Source source = new Issue3807Mapper.Source( "value" ); + Issue3807Mapper.TargetWithoutSetter targetWithoutSetter = + Issue3807Mapper.INSTANCE.mapNoSetter( source ); + + assertThat( targetWithoutSetter ).isNotNull(); + assertThat( targetWithoutSetter.value ).isEqualTo( "value" ); + + Issue3807Mapper.NormalTarget normalTarget = Issue3807Mapper.INSTANCE.mapNormalSource( source ); + + assertThat( normalTarget ).isNotNull(); + assertThat( normalTarget.getValue() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3809/Issue3809Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3809/Issue3809Mapper.java new file mode 100644 index 0000000000..10ff9e2628 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3809/Issue3809Mapper.java @@ -0,0 +1,69 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3809; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.TargetPropertyName; + +@Mapper +public interface Issue3809Mapper { + void updateMappingFails(Source source, @MappingTarget Target target); + + @Condition + default boolean canMap(Object source, @TargetPropertyName String propertyName) { + return true; + } + + class Source { + private NestedSource param; + + public NestedSource getParam() { + return param; + } + } + + class NestedSource { + private String param1; + + public String getParam1() { + return param1; + } + + public void setParam1(String param1) { + this.param1 = param1; + } + + } + + class Target { + + private NestedTarget param; + + public NestedTarget getParam() { + return param; + } + + public void setParam(NestedTarget param) { + this.param = param; + } + + } + + class NestedTarget { + private String param1; + + public String getParam1() { + return param1; + } + + public void setParam1(String param1) { + this.param1 = param1; + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3809/Issue3809Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3809/Issue3809Test.java new file mode 100644 index 0000000000..23d97b877c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3809/Issue3809Test.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3809; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +@WithClasses(Issue3809Mapper.class) +@IssueKey("3809") +public class Issue3809Test { + + @ProcessorTest + public void shouldCompileNoError() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Child.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Child.java new file mode 100644 index 0000000000..393cb16970 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Child.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +public class Child extends Parent { + public Child() { + super(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/ChildDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/ChildDto.java new file mode 100644 index 0000000000..e8cdae4d17 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/ChildDto.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +public class ChildDto extends ParentDto { + public ChildDto(String value) { + super( value ); + } + + public void setValue(String value) { + super.setValue( value ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateBySourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateBySourceMapper.java new file mode 100644 index 0000000000..68450c7d9d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateBySourceMapper.java @@ -0,0 +1,69 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DeduplicateBySourceMapper { + + DeduplicateBySourceMapper INSTANCE = Mappers.getMapper( DeduplicateBySourceMapper.class ); + List INVOKED_METHODS = new ArrayList<>(); + + ParentDto mapParent(Parent source, @Context MappingContext context); + + ParentDto mapChild(Child source, @Context MappingContext context); + + class MappingContext { + @BeforeMapping + void deduplicateBySourceForBefore(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingParentSourceInOtherClass" ); + } + + @BeforeMapping + void deduplicateBySourceForBefore(Child sourceChild, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingChildSourceInOtherClass" ); + } + + @AfterMapping + void deduplicateBySource(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParentSourceInOtherClass" ); + } + + @AfterMapping + void deduplicateBySource(Child sourceChild, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingChildSourceInOtherClass" ); + } + } + + @BeforeMapping + default void deduplicateBySourceForBefore(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingParentSource" ); + } + + @BeforeMapping + default void deduplicateBySourceForBefore(Child sourceChild, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingChildSource" ); + } + + @AfterMapping + default void deduplicateBySource(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParentSource" ); + } + + @AfterMapping + default void deduplicateBySource(Child sourceChild, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingChildSource" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateByTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateByTargetMapper.java new file mode 100644 index 0000000000..0aed8a2957 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateByTargetMapper.java @@ -0,0 +1,69 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DeduplicateByTargetMapper { + + DeduplicateByTargetMapper INSTANCE = Mappers.getMapper( DeduplicateByTargetMapper.class ); + List INVOKED_METHODS = new ArrayList<>(); + + ParentDto mapParent(Parent source, @Context MappingContext context); + + ChildDto mapChild(Parent source, @Context MappingContext context); + + class MappingContext { + @BeforeMapping + void deduplicateByTargetForBefore(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingParentTargetInOtherClass" ); + } + + @BeforeMapping + void deduplicateByTargetForBefore(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "beforeMappingChildTargetInOtherClass" ); + } + + @AfterMapping + void deduplicateByTarget(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParentTargetInOtherClass" ); + } + + @AfterMapping + void deduplicateByTarget(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "afterMappingChildTargetInOtherClass" ); + } + } + + @BeforeMapping + default void deduplicateByTargetForBefore(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingParentTarget" ); + } + + @BeforeMapping + default void deduplicateByTargetForBefore(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "beforeMappingChildTarget" ); + } + + @AfterMapping + default void deduplicateByTarget(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParentTarget" ); + } + + @AfterMapping + default void deduplicateByTarget(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "afterMappingChildTarget" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateForCompileArgsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateForCompileArgsMapper.java new file mode 100644 index 0000000000..276a2c4352 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateForCompileArgsMapper.java @@ -0,0 +1,69 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DeduplicateForCompileArgsMapper { + + DeduplicateForCompileArgsMapper INSTANCE = Mappers.getMapper( DeduplicateForCompileArgsMapper.class ); + List INVOKED_METHODS = new ArrayList<>(); + + ParentDto mapParent(Parent source, @Context MappingContext context); + + ChildDto mapChild(Parent source, @Context MappingContext context); + + class MappingContext { + @BeforeMapping + void deduplicateByTargetForBefore(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingParentTargetInOtherClass" ); + } + + @BeforeMapping + void deduplicateByTargetForBefore(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "beforeMappingChildTargetInOtherClass" ); + } + + @AfterMapping + void deduplicateByTarget(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParentTargetInOtherClass" ); + } + + @AfterMapping + void deduplicateByTarget(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "afterMappingChildTargetInOtherClass" ); + } + } + + @BeforeMapping + default void deduplicateByTargetForBefore(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "beforeMappingParentTarget" ); + } + + @BeforeMapping + default void deduplicateByTargetForBefore(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "beforeMappingChildTarget" ); + } + + @AfterMapping + default void deduplicateByTarget(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParentTarget" ); + } + + @AfterMapping + default void deduplicateByTarget(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "afterMappingChildTarget" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateGenericMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateGenericMapper.java new file mode 100644 index 0000000000..662137f1a9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/DeduplicateGenericMapper.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DeduplicateGenericMapper { + + DeduplicateGenericMapper INSTANCE = Mappers.getMapper( DeduplicateGenericMapper.class ); + List INVOKED_METHODS = new ArrayList<>(); + + ParentDto mapParent(Parent source); + + ChildDto mapChild(Parent source); + + @BeforeMapping + default void deduplicateBefore(Parent source, @MappingTarget T target) { + INVOKED_METHODS.add( "beforeMappingParentGeneric" ); + } + + @BeforeMapping + default void deduplicateBefore(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "beforeMappingChild" ); + } + + @AfterMapping + default void deduplicate(Parent source, @MappingTarget T target) { + INVOKED_METHODS.add( "afterMappingGeneric" ); + } + + @AfterMapping + default void deduplicate(Parent source, @MappingTarget ParentDto target) { + INVOKED_METHODS.add( "afterMappingParent" ); + } + + @AfterMapping + default void deduplicate(Parent source, @MappingTarget ChildDto target) { + INVOKED_METHODS.add( "afterMappingChild" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Issue3849Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Issue3849Test.java new file mode 100644 index 0000000000..a58c52c921 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Issue3849Test.java @@ -0,0 +1,150 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.bugs._3849; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("3849") +@WithClasses({ + Parent.class, + ParentDto.class, + Child.class, + ChildDto.class +}) +public class Issue3849Test { + + @ProcessorOption(name = "mapstruct.disableLifecycleOverloadDeduplicateSelector", value = "true") + @ProcessorTest() + @WithClasses(DeduplicateForCompileArgsMapper.class) + void lifecycleMappingOverloadSelectorDisableCompileArgs() { + Child child = new Child(); + Parent parent = new Parent(); + + DeduplicateForCompileArgsMapper.MappingContext mappingContext = + new DeduplicateForCompileArgsMapper.MappingContext(); + ParentDto parentDto = DeduplicateForCompileArgsMapper.INSTANCE.mapParent( parent, mappingContext ); + assertThat( DeduplicateForCompileArgsMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingParentTargetInOtherClass", + "beforeMappingParentTarget", + "afterMappingParentTargetInOtherClass", + "afterMappingParentTarget" + ); + + DeduplicateForCompileArgsMapper.INVOKED_METHODS.clear(); + + ParentDto childDto = DeduplicateForCompileArgsMapper.INSTANCE.mapChild( child, mappingContext ); + + assertThat( DeduplicateForCompileArgsMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingChildTargetInOtherClass", + "beforeMappingChildTargetInOtherClass", + "beforeMappingChildTarget", + "beforeMappingChildTarget", + "afterMappingChildTargetInOtherClass", + "afterMappingChildTargetInOtherClass", + "afterMappingChildTarget", + "afterMappingChildTarget" + ); + + DeduplicateForCompileArgsMapper.INVOKED_METHODS.clear(); + } + + @ProcessorTest() + @WithClasses( DeduplicateByTargetMapper.class ) + void lifecycleMappingOverloadByTarget() { + Child child = new Child(); + Parent parent = new Parent(); + + DeduplicateByTargetMapper.MappingContext mappingContext = new DeduplicateByTargetMapper.MappingContext(); + ParentDto parentDto = DeduplicateByTargetMapper.INSTANCE.mapParent( parent, mappingContext ); + assertThat( DeduplicateByTargetMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingParentTargetInOtherClass", + "beforeMappingParentTarget", + "afterMappingParentTargetInOtherClass", + "afterMappingParentTarget" + ); + + DeduplicateByTargetMapper.INVOKED_METHODS.clear(); + + ParentDto childDto = DeduplicateByTargetMapper.INSTANCE.mapChild( child, mappingContext ); + + assertThat( DeduplicateByTargetMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingChildTargetInOtherClass", + "beforeMappingChildTarget", + "afterMappingChildTargetInOtherClass", + "afterMappingChildTarget" + ); + + DeduplicateByTargetMapper.INVOKED_METHODS.clear(); + } + + @ProcessorTest + @WithClasses( DeduplicateBySourceMapper.class ) + void lifecycleMappingOverloadBySource() { + Child child = new Child(); + Parent parent = new Parent(); + + DeduplicateBySourceMapper.MappingContext mappingContext = new DeduplicateBySourceMapper.MappingContext(); + ParentDto parentDto = DeduplicateBySourceMapper.INSTANCE.mapParent( parent, mappingContext ); + assertThat( DeduplicateBySourceMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingParentSourceInOtherClass", + "beforeMappingParentSource", + "afterMappingParentSourceInOtherClass", + "afterMappingParentSource" + ); + + DeduplicateBySourceMapper.INVOKED_METHODS.clear(); + + ParentDto childDto = DeduplicateBySourceMapper.INSTANCE.mapChild( child, mappingContext ); + + assertThat( DeduplicateBySourceMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingChildSourceInOtherClass", + "beforeMappingChildSource", + "afterMappingChildSourceInOtherClass", + "afterMappingChildSource" + ); + + DeduplicateBySourceMapper.INVOKED_METHODS.clear(); + } + + @ProcessorTest + @WithClasses(DeduplicateGenericMapper.class) + void lifecycleMappingOverloadForGeneric() { + Child child = new Child(); + Parent parent = new Parent(); + + ParentDto parentDto = DeduplicateGenericMapper.INSTANCE.mapParent( parent ); + assertThat( DeduplicateGenericMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingParentGeneric", + "afterMappingParent" + ); + + DeduplicateGenericMapper.INVOKED_METHODS.clear(); + + ParentDto childDto = DeduplicateGenericMapper.INSTANCE.mapChild( child ); + + assertThat( DeduplicateGenericMapper.INVOKED_METHODS ) + .containsExactly( + "beforeMappingChild", + "afterMappingChild" + ); + + DeduplicateGenericMapper.INVOKED_METHODS.clear(); + } +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Parent.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Parent.java new file mode 100644 index 0000000000..4930677286 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/Parent.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +public class Parent { + private String value; + + public Parent() { + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/ParentDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/ParentDto.java new file mode 100644 index 0000000000..098917f001 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3849/ParentDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3849; + +public class ParentDto { + private String value; + + public ParentDto(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/DestinationType.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/DestinationType.java new file mode 100644 index 0000000000..467b58990c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/DestinationType.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3884; + +import java.util.List; +import java.util.Map; + +/** + * Destination type interface for testing null value property mapping strategy with Map properties. + */ +public interface DestinationType { + Map getAttributes(); + + void setAttributes(Map attributes); + + List getItems(); + + void setItems(List items); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/Issue3884Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/Issue3884Mapper.java new file mode 100644 index 0000000000..6f6f4f924d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/Issue3884Mapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3884; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * Mapper for testing null value property mapping strategy with Map properties. + */ +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) +public interface Issue3884Mapper { + Issue3884Mapper INSTANCE = Mappers.getMapper( Issue3884Mapper.class ); + + void update(@MappingTarget DestinationType destination, SourceType source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/Issue3884Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/Issue3884Test.java new file mode 100644 index 0000000000..6c789a0c29 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/Issue3884Test.java @@ -0,0 +1,116 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3884; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +/** + * Test for issue 3884: NullValuePropertyMappingStrategy.SET_TO_DEFAULT should set target Map/Collection to default + * when source and target are all null. + */ +@IssueKey("3884") +@WithClasses({ + DestinationType.class, + SourceType.class, + Issue3884Mapper.class +}) +public class Issue3884Test { + + @ProcessorTest + public void shouldSetTargetToDefaultWhenBothSourceAndTargetAreNull() { + DestinationType target = new SourceType(); + SourceType source = new SourceType(); + + assertThat( source.getAttributes() ).isNull(); + assertThat( target.getAttributes() ).isNull(); + assertThat( source.getItems() ).isNull(); + assertThat( target.getItems() ).isNull(); + + Issue3884Mapper.INSTANCE.update( target, source ); + + assertThat( target.getAttributes() ).isEmpty(); + assertThat( target.getItems() ).isEmpty(); + } + + @ProcessorTest + public void shouldClearTargetWhenSourceIsNullAndTargetIsInitialized() { + DestinationType target = new SourceType(); + SourceType source = new SourceType(); + + Map targetAttributes = new HashMap<>(); + targetAttributes.put( "targetKey", "targetValue" ); + target.setAttributes( targetAttributes ); + + List targetItems = new ArrayList<>(); + targetItems.add( "targetItem" ); + target.setItems( targetItems ); + + assertThat( source.getAttributes() ).isNull(); + assertThat( target.getAttributes() ).isNotEmpty(); + assertThat( source.getItems() ).isNull(); + assertThat( target.getItems() ).isNotEmpty(); + + Issue3884Mapper.INSTANCE.update( target, source ); + + assertThat( target.getAttributes() ).isEmpty(); + assertThat( target.getItems() ).isEmpty(); + } + + @ProcessorTest + public void shouldCopySourceToTargetWhenSourceIsInitializedAndTargetIsNull() { + DestinationType target = new SourceType(); + SourceType source = new SourceType(); + + source.setAttributes( Map.of( "sourceKey", "sourceValue" ) ); + source.setItems( List.of( "sourceItem" ) ); + + assertThat( source.getAttributes() ).isNotEmpty(); + assertThat( target.getAttributes() ).isNull(); + assertThat( source.getItems() ).isNotEmpty(); + assertThat( target.getItems() ).isNull(); + + Issue3884Mapper.INSTANCE.update( target, source ); + + assertThat( target.getAttributes() ).containsOnly( entry( "sourceKey", "sourceValue" ) ); + assertThat( target.getItems() ).containsExactly( "sourceItem" ); + } + + @ProcessorTest + public void shouldCopySourceToTargetWhenBothSourceAndTargetAreInitialized() { + DestinationType target = new SourceType(); + SourceType source = new SourceType(); + + source.setAttributes( Map.of( "sourceKey", "sourceValue" ) ); + source.setItems( List.of( "sourceItem" ) ); + + Map targetAttributes = new HashMap<>(); + targetAttributes.put( "targetKey", "targetValue" ); + target.setAttributes( targetAttributes ); + List targetItems = new ArrayList<>(); + targetItems.add( "targetItem" ); + target.setItems( targetItems ); + + assertThat( source.getAttributes() ).isNotEmpty(); + assertThat( target.getAttributes() ).isNotEmpty(); + assertThat( source.getItems() ).isNotEmpty(); + assertThat( target.getItems() ).isNotEmpty(); + + Issue3884Mapper.INSTANCE.update( target, source ); + + assertThat( target.getAttributes() ).containsOnly( entry( "sourceKey", "sourceValue" ) ); + assertThat( target.getItems() ).containsExactly( "sourceItem" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/SourceType.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/SourceType.java new file mode 100644 index 0000000000..be5c19e01c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3884/SourceType.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3884; + +import java.util.List; +import java.util.Map; + +/** + * Source type class implementing DestinationType for testing null value property mapping strategy with Map properties. + */ +public class SourceType implements DestinationType { + private Map attributes; + private List items; + + @Override + public Map getAttributes() { + return attributes; + } + + @Override + public void setAttributes(Map attributes) { + this.attributes = attributes; + } + + @Override + public List getItems() { + return items; + } + + @Override + public void setItems(List items) { + this.items = items; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3886/jdk21/Issue3886Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3886/jdk21/Issue3886Mapper.java new file mode 100644 index 0000000000..aba305a0bf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3886/jdk21/Issue3886Mapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3886.jdk21; + +import java.time.LocalDate; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface Issue3886Mapper { + + RangeRecord map(LocalDate validFrom); + + record RangeRecord(LocalDate validFrom) { + + public RangeRecord restrictTo(RangeRecord other) { + return null; + } + + public void setName(String name) { + // This method is here to ensure that MapStruct won't treat it as a setter + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3886/jdk21/Issue3886Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3886/jdk21/Issue3886Test.java new file mode 100644 index 0000000000..93c068cbc7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3886/jdk21/Issue3886Test.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3886.jdk21; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.Compiler; + +/** + * @author Filip Hrisafov + */ +@WithClasses(Issue3886Mapper.class) +@IssueKey("3886") +class Issue3886Test { + + // The current version of the Eclipse compiler we use does not support records + @ProcessorTest(Compiler.JDK) + void shouldCompile() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3902/ErroneousIssue3902Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3902/ErroneousIssue3902Mapper.java new file mode 100644 index 0000000000..b646f1a08e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3902/ErroneousIssue3902Mapper.java @@ -0,0 +1,72 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3902; + +import org.mapstruct.Ignored; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * Mapper for testing bug #3902. + * + * @author znight1020 + */ +@Mapper +public interface ErroneousIssue3902Mapper { + + ErroneousIssue3902Mapper INSTANCE = Mappers.getMapper( ErroneousIssue3902Mapper.class ); + + @Ignored(targets = {"name", "foo", "bar"}) + ZooDto mapWithOneKnownAndMultipleUnknowns(Zoo source); + + @Ignored(targets = {"name", "address", "foo"}) + ZooDto mapWithMultipleKnownAndOneUnknown(Zoo source); + + @Ignored(targets = {"name", "addres"}) + ZooDto mapWithTypo(Zoo source); + + class Zoo { + private String name; + private String address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } + + class ZooDto { + private String name; + private String address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3902/Issue3902Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3902/Issue3902Test.java new file mode 100644 index 0000000000..44247d8c27 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3902/Issue3902Test.java @@ -0,0 +1,66 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3902; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * Verifies that using an unknown property in {@code @Ignored} yields a proper + * compile error instead of an internal processor error. + * + * @author znight1020 + */ +@WithClasses({ErroneousIssue3902Mapper.class}) +@IssueKey("3902") +public class Issue3902Test { + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + // Test case: mapWithOneKnownAndMultipleUnknowns + @Diagnostic( + type = ErroneousIssue3902Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 23, + message = "No property named \"foo\" exists in @Ignored for target type " + + "\"ErroneousIssue3902Mapper.ZooDto\". Did you mean \"name\"?" + ), + @Diagnostic( + type = ErroneousIssue3902Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 23, + message = "No property named \"bar\" exists in @Ignored for target type " + + "\"ErroneousIssue3902Mapper.ZooDto\". Did you mean \"name\"?" + ), + + // Test case: mapWithMultipleKnownAndOneUnknown + @Diagnostic( + type = ErroneousIssue3902Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 26, + message = "No property named \"foo\" exists in @Ignored for target type " + + "\"ErroneousIssue3902Mapper.ZooDto\". Did you mean \"name\"?" + ), + + // Test case: mapWithTypo + @Diagnostic( + type = ErroneousIssue3902Mapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 29, + message = "No property named \"addres\" exists in @Ignored for target type " + + "\"ErroneousIssue3902Mapper.ZooDto\". Did you mean \"address\"?" + ) + } + ) + public void shouldFailOnUnknownPropertiesInIgnored() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Issue3905Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Issue3905Mapper.java new file mode 100644 index 0000000000..27e3ac9960 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Issue3905Mapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3905; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface Issue3905Mapper { + + OverrideDto map(Override override); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Issue3905Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Issue3905Test.java new file mode 100644 index 0000000000..f15271362d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Issue3905Test.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3905; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author Filip Hrisafov + */ +@IssueKey("3905") +@WithClasses({ + Issue3905Mapper.class, + Override.class, + OverrideDto.class +}) +class Issue3905Test { + + @ProcessorTest + void shouldCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Override.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Override.java new file mode 100644 index 0000000000..dedc6b28dc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/Override.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3905; + +/** + * @author Filip Hrisafov + */ +public class Override { + + private final String name; + + public Override(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/OverrideDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/OverrideDto.java new file mode 100644 index 0000000000..531fab505b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3905/OverrideDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3905; + +/** + * @author Filip Hrisafov + */ +public class OverrideDto { + + private final String name; + + public OverrideDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameClassNameInDifferentPackageTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameClassNameInDifferentPackageTest.java index 9a0311961f..78cbc6177e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameClassNameInDifferentPackageTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameClassNameInDifferentPackageTest.java @@ -1,35 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._394; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.HashMap; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._394.source.AnotherCar; import org.mapstruct.ap.test.bugs._394.source.Cars; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses( { SameNameForSourceAndTargetCarsMapper.class, @@ -39,10 +24,9 @@ org.mapstruct.ap.test.bugs._394._target.AnotherCar.class } ) @IssueKey("394") -@RunWith(AnnotationProcessorTestRunner.class) public class SameClassNameInDifferentPackageTest { - @Test + @ProcessorTest public void shouldCreateMapMethodImplementation() { Map values = new HashMap(); //given diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameNameForSourceAndTargetCarsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameNameForSourceAndTargetCarsMapper.java index 2364b17ca3..1d43087a51 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameNameForSourceAndTargetCarsMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/SameNameForSourceAndTargetCarsMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._394; @@ -34,7 +21,7 @@ public interface SameNameForSourceAndTargetCarsMapper { SameNameForSourceAndTargetCarsMapper INSTANCE = Mappers.getMapper( SameNameForSourceAndTargetCarsMapper.class ); @Mappings({ - @Mapping(source = "numberOfSeats", target = "seatCount") + @Mapping(target = "seatCount", source = "numberOfSeats") }) AnotherCar sourceCarToTargetCar(org.mapstruct.ap.test.bugs._394.source.AnotherCar car); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/AnotherCar.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/AnotherCar.java index 9003a7d43f..bd99d6f524 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/AnotherCar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/AnotherCar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._394._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/Cars.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/Cars.java index 233701beea..185e52e046 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/Cars.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/_target/Cars.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._394._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/AnotherCar.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/AnotherCar.java index 0b0e2ecf70..0d050196e5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/AnotherCar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/AnotherCar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._394.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/Cars.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/Cars.java index 6a22c6a37a..68bac36095 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/Cars.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_394/source/Cars.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._394.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3948/Issue3948Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3948/Issue3948Mapper.java new file mode 100644 index 0000000000..ab053bc44e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3948/Issue3948Mapper.java @@ -0,0 +1,93 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3948; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface Issue3948Mapper { + + class ComparableField implements Comparable { + + private final String code; + + public ComparableField(String code) { + this.code = code; + } + + @Override + public int compareTo(ComparableField o) { + return code.compareTo( o.code ); + } + } + + class Id implements Comparable> { + private final long value; + + public Id(long value) { + this.value = value; + } + + @Override + public int compareTo(Id o) { + return Long.compare( value, o.value ); + } + } + + class From { + private long id; + private String code; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + } + + class To { + private Id id; + private ComparableField comparableField; + + public Id getId() { + return id; + } + + public void setId(Id id) { + this.id = id; + } + + public ComparableField getComparableField() { + return comparableField; + } + + public void setComparableField(ComparableField comparableField) { + this.comparableField = comparableField; + } + } + + @Mapping(source = "code", target = "comparableField") + To convert(From from); + + default Id longToId(Long id) { + return id == null ? null : new Id<>(id); + } + + default ComparableField convert(String code) { + return code == null ? null : new ComparableField(code); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3948/Issue3948Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3948/Issue3948Test.java new file mode 100644 index 0000000000..8c80b2e802 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3948/Issue3948Test.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3948; + +import org.junitpioneer.jupiter.Issue; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +/** + * @author hduelme + */ +@Issue("3948") +public class Issue3948Test { + + @ProcessorTest + @WithClasses(Issue3948Mapper.class) + public void shouldRequireExactGenericMatchForDeclaredSameTypes() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/DateSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/DateSource.java new file mode 100644 index 0000000000..e542c388d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/DateSource.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import java.time.LocalDate; + +public class DateSource { + public LocalDate getDate() { + return null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949ClassMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949ClassMapper.java new file mode 100644 index 0000000000..135aa79056 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949ClassMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL) +public interface Issue3949ClassMapper { + + Issue3949ClassMapper INSTANCE = Mappers.getMapper( Issue3949ClassMapper.class ); + + void overwriteDate(@MappingTarget TargetDate target, DateSource dateSource); + + void overwriteString(@MappingTarget TargetString target, StringSource stringSource); + + void overwriteDateWithConversion(@MappingTarget TargetDate target, StringSource dateSource); + + void overwriteStringWithConversion(@MappingTarget TargetString target, DateSource stringSource); + + void updateParent(@MappingTarget ParentTarget target, ParentSource source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949InterfaceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949InterfaceMapper.java new file mode 100644 index 0000000000..c25041ad2f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949InterfaceMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_NULL) +public interface Issue3949InterfaceMapper { + + Issue3949InterfaceMapper INSTANCE = Mappers.getMapper( Issue3949InterfaceMapper.class ); + + void overwriteDate(@MappingTarget TargetDateInterface target, DateSource dateSource); + + void overwriteString(@MappingTarget TargetStringInterface target, StringSource stringSource); + + void overwriteDateWithConversion(@MappingTarget TargetDateInterface target, StringSource dateSource); + + void overwriteStringWithConversion(@MappingTarget TargetStringInterface target, DateSource stringSource); + + void updateParent(@MappingTarget ParentTargetInterface target, ParentSource source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949Test.java new file mode 100644 index 0000000000..b6abee819c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/Issue3949Test.java @@ -0,0 +1,94 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests if overloaded targets are correctly cast when set to null + * + * @author hduelme + */ +@IssueKey("3949") +@WithClasses({ + ParentSource.class, + ParentTargetInterface.class, + ParentTarget.class, + StringSource.class, + TargetStringInterface.class, + TargetString.class, + DateSource.class, + TargetDateInterface.class, + TargetDate.class +}) +public class Issue3949Test { + + @ProcessorTest + @WithClasses({ + Issue3949ClassMapper.class + }) + void shouldCompileAndSetCorrectlyToNullForClass() { + TargetDate shouldSetDateToNull = new TargetDate(); + Issue3949ClassMapper.INSTANCE.overwriteDate( shouldSetDateToNull, new DateSource() ); + assertThat( shouldSetDateToNull.getString() ).isNotNull(); + assertThat( shouldSetDateToNull.getDate() ).isNull(); + + shouldSetDateToNull = new TargetDate(); + Issue3949ClassMapper.INSTANCE.overwriteDateWithConversion( shouldSetDateToNull, new StringSource() ); + assertThat( shouldSetDateToNull.getString() ).isNotNull(); + assertThat( shouldSetDateToNull.getDate() ).isNull(); + + TargetString shouldSetStringToNull = new TargetString(); + Issue3949ClassMapper.INSTANCE.overwriteString( shouldSetStringToNull, new StringSource() ); + assertThat( shouldSetStringToNull.getDate() ).isNull(); + assertThat( shouldSetStringToNull.getDateValue() ).isNotNull(); + + shouldSetStringToNull = new TargetString(); + Issue3949ClassMapper.INSTANCE.overwriteStringWithConversion( shouldSetStringToNull, new DateSource() ); + assertThat( shouldSetStringToNull.getDate() ).isNull(); + assertThat( shouldSetStringToNull.getDateValue() ).isNotNull(); + + ParentTarget parentTarget = new ParentTarget(); + parentTarget.setChild( new ParentTarget() ); + Issue3949ClassMapper.INSTANCE.updateParent( parentTarget, new ParentSource() ); + assertThat( parentTarget.getChild() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + Issue3949InterfaceMapper.class + }) + void shouldCompileAndSetCorrectlyToNullForInterface() { + TargetDateInterface shouldSetDateToNull = new TargetDate(); + Issue3949InterfaceMapper.INSTANCE.overwriteDate( shouldSetDateToNull, new DateSource() ); + assertThat( shouldSetDateToNull.getString() ).isNotNull(); + assertThat( shouldSetDateToNull.getDate() ).isNull(); + + shouldSetDateToNull = new TargetDate(); + Issue3949InterfaceMapper.INSTANCE.overwriteDateWithConversion( shouldSetDateToNull, new StringSource() ); + assertThat( shouldSetDateToNull.getString() ).isNotNull(); + assertThat( shouldSetDateToNull.getDate() ).isNull(); + + TargetStringInterface shouldSetStringToNull = new TargetString(); + Issue3949InterfaceMapper.INSTANCE.overwriteString( shouldSetStringToNull, new StringSource() ); + assertThat( shouldSetStringToNull.getDate() ).isNull(); + assertThat( shouldSetStringToNull.getDateValue() ).isNotNull(); + + shouldSetStringToNull = new TargetString(); + Issue3949InterfaceMapper.INSTANCE.overwriteStringWithConversion( shouldSetStringToNull, new DateSource() ); + assertThat( shouldSetStringToNull.getDate() ).isNull(); + assertThat( shouldSetStringToNull.getDateValue() ).isNotNull(); + + ParentTargetInterface parentTarget = new ParentTarget(); + parentTarget.setChild( new ParentTarget() ); + Issue3949InterfaceMapper.INSTANCE.updateParent( parentTarget, new ParentSource() ); + assertThat( parentTarget.getChild() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentSource.java new file mode 100644 index 0000000000..551501aa24 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentSource.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +public class ParentSource { + public ParentSource getChild() { + return null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentTarget.java new file mode 100644 index 0000000000..3d8ca3b51b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentTarget.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +public class ParentTarget implements ParentTargetInterface { + private ParentTarget child; + + @Override + public ParentTarget getChild() { + return child; + } + + @Override + public void setChild(String child) { + throw new IllegalArgumentException(); + } + + @Override + public void setChild(ParentTarget child) { + this.child = child; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentTargetInterface.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentTargetInterface.java new file mode 100644 index 0000000000..5311fb4c9b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/ParentTargetInterface.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +public interface ParentTargetInterface { + ParentTarget getChild(); + + void setChild(String child); + + void setChild(ParentTarget child); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/StringSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/StringSource.java new file mode 100644 index 0000000000..11ba1419d5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/StringSource.java @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +public class StringSource { + public String getDate() { + return null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetDate.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetDate.java new file mode 100644 index 0000000000..85b12a618d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetDate.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import java.time.LocalDate; + +public class TargetDate implements TargetDateInterface { + private LocalDate date = LocalDate.now(); + private String string = ""; + + @Override + public void setDate(LocalDate date) { + this.date = date; + } + + @Override + public void setDate(String date) { + this.string = date; + } + + @Override + public LocalDate getDate() { + return date; + } + + @Override + public String getString() { + return string; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetDateInterface.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetDateInterface.java new file mode 100644 index 0000000000..df28936914 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetDateInterface.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import java.time.LocalDate; + +public interface TargetDateInterface { + void setDate(LocalDate date); + + void setDate(String date); + + LocalDate getDate(); + + String getString(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetString.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetString.java new file mode 100644 index 0000000000..b8cbbb2bbb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetString.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import java.time.LocalDate; + +public class TargetString implements TargetStringInterface { + private LocalDate date = LocalDate.now(); + private String string = ""; + + @Override + public void setDate(LocalDate date) { + this.date = date; + } + + @Override + public void setDate(String date) { + this.string = date; + } + + @Override + public String getDate() { + return string; + } + + @Override + public LocalDate getDateValue() { + return date; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetStringInterface.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetStringInterface.java new file mode 100644 index 0000000000..dd82231a51 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_3949/TargetStringInterface.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._3949; + +import java.time.LocalDate; + +public interface TargetStringInterface { + void setDate(LocalDate date); + + void setDate(String date); + + String getDate(); + + LocalDate getDateValue(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/EntityFactory.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/EntityFactory.java index a86dd77590..77811f4ad9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/EntityFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/EntityFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._405; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Issue405Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Issue405Test.java index 0eecf73222..f1f34ee394 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Issue405Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Issue405Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._405; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/405. @@ -30,10 +15,9 @@ * @author Sjaak Derksen */ @IssueKey( "405" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue405Test { - @Test + @ProcessorTest @WithClasses( { EntityFactory.class, Person.class, People.class, PersonMapper.class } ) public void shouldGenerateFactoryCorrectMethodForIterables() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/People.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/People.java index d59d86f6ec..87e7ab8818 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/People.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/People.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._405; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Person.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Person.java index 7883db38b9..36c119cd41 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._405; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/PersonMapper.java index a1ebaf0e8b..4be1356aed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_405/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._405; @@ -32,7 +19,7 @@ public abstract class PersonMapper { public static final PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class ); @Mappings( { - @Mapping( source = "id", target = "name" ) } + @Mapping(target = "name", source = "id") } ) abstract People personToPeople(Person person); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/ErroneousSetToDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/ErroneousSetToDefaultMapper.java new file mode 100644 index 0000000000..4ede382781 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/ErroneousSetToDefaultMapper.java @@ -0,0 +1,100 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._4060; + +import java.math.BigDecimal; +import java.time.LocalDate; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; + +@Mapper +public interface ErroneousSetToDefaultMapper { + + class WithLocalDate { + private LocalDate value; + + public LocalDate getValue() { + return value; + } + + public void setValue(LocalDate value) { + this.value = value; + } + } + + class WithBigDecimal { + private BigDecimal value; + + public BigDecimal getValue() { + return value; + } + + public void setValue(BigDecimal value) { + this.value = value; + } + } + + class WithComparable { + private Comparable value; + + public Comparable getValue() { + return value; + } + + public void setValue(Comparable value) { + this.value = value; + } + } + + abstract class AbstractValue { + } + + class WithAbstractValue { + private AbstractValue value; + + public AbstractValue getValue() { + return value; + } + + public void setValue(AbstractValue value) { + this.value = value; + } + } + + enum EnumValue { + FIRST + } + + class WithEnumValue { + private EnumValue value; + + public EnumValue getValue() { + return value; + } + + public void setValue(EnumValue value) { + this.value = value; + } + } + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + void updateLocalDate(@MappingTarget WithLocalDate target, WithLocalDate source); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + void updateBigDecimal(@MappingTarget WithBigDecimal target, WithBigDecimal source); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + void updateComparable(@MappingTarget WithComparable target, WithComparable source); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + void updateAbstractValue(@MappingTarget WithAbstractValue target, WithAbstractValue source); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + void updateEnumValue(@MappingTarget WithEnumValue target, WithEnumValue source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/Issue4060Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/Issue4060Test.java new file mode 100644 index 0000000000..e0e51dac32 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/Issue4060Test.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._4060; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("4060") +public class Issue4060Test { + + @ProcessorTest + @WithClasses(ErroneousSetToDefaultMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousSetToDefaultMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 87, + message = "LocalDate does not have an accessible parameterless constructor. " + + "Either change the nullValuePropertyMappingStrategy or define a defaultValue " + + "or a defaultExpression."), + @Diagnostic(type = ErroneousSetToDefaultMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 90, + message = "BigDecimal does not have an accessible parameterless constructor. " + + "Either change the nullValuePropertyMappingStrategy or define a defaultValue " + + "or a defaultExpression."), + @Diagnostic(type = ErroneousSetToDefaultMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 93, + message = "Comparable does not have an accessible parameterless constructor. " + + "Either change the nullValuePropertyMappingStrategy or define a defaultValue " + + "or a defaultExpression."), + @Diagnostic(type = ErroneousSetToDefaultMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 96, + message = "ErroneousSetToDefaultMapper.AbstractValue does not have an accessible " + + "parameterless constructor. " + + "Either change the nullValuePropertyMappingStrategy or define a defaultValue " + + "or a defaultExpression."), + @Diagnostic(type = ErroneousSetToDefaultMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 99, + message = "ErroneousSetToDefaultMapper.EnumValue does not have an accessible " + + "parameterless constructor. " + + "Either change the nullValuePropertyMappingStrategy or define a defaultValue " + + "or a defaultExpression.") + }) + void setToDefaultWithoutParameterlessConstructorFails() { + } + + @ProcessorTest + @WithClasses(SetToDefaultMapper.class) + void setToDefaultWithParameterlessConstructorResetsToNewInstance() { + SetToDefaultMapper.Target target = new SetToDefaultMapper.Target(); + SetToDefaultMapper.Nested existing = new SetToDefaultMapper.Nested(); + existing.setName( "existing" ); + target.setNested( existing ); + target.setText( "existing" ); + + SetToDefaultMapper.INSTANCE.update( target, new SetToDefaultMapper.Source() ); + + // source properties are null, SET_TO_DEFAULT resets them to a fresh default + assertThat( target.getNested() ).isNotNull(); + assertThat( target.getNested() ).isNotSameAs( existing ); + assertThat( target.getNested().getName() ).isNull(); + assertThat( target.getText() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/SetToDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/SetToDefaultMapper.java new file mode 100644 index 0000000000..edfe7e9b3b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_4060/SetToDefaultMapper.java @@ -0,0 +1,75 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._4060; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SetToDefaultMapper { + + SetToDefaultMapper INSTANCE = Mappers.getMapper( SetToDefaultMapper.class ); + + class Nested { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + + class Target { + private Nested nested; + private String text; + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + } + + class Source { + private Nested nested; + private String text; + + public Nested getNested() { + return nested; + } + + public void setNested(Nested nested) { + this.nested = nested; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + } + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + void update(@MappingTarget Target target, Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Mapper.java index 09df5cb258..32cf02e3af 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Test.java index 545c1e3df9..9bc5be096e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Issue513Test.java @@ -1,31 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; import java.util.Arrays; import java.util.HashMap; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/513. @@ -47,63 +34,66 @@ MappingKeyException.class, MappingValueException.class } ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue513Test { - @Test( expected = MappingException.class ) + @ProcessorTest public void shouldThrowMappingException() throws Exception { Source source = new Source(); SourceElement sourceElement = new SourceElement(); sourceElement.setValue( "test" ); - source.setCollection( Arrays.asList( new SourceElement[]{ sourceElement } ) ); + source.setCollection( Arrays.asList( sourceElement ) ); - Issue513Mapper.INSTANCE.map( source ); + assertThatThrownBy( () -> Issue513Mapper.INSTANCE.map( source ) ) + .isInstanceOf( MappingException.class ); } - @Test( expected = MappingKeyException.class ) + @ProcessorTest public void shouldThrowMappingKeyException() throws Exception { Source source = new Source(); SourceKey sourceKey = new SourceKey(); sourceKey.setValue( MappingKeyException.class.getSimpleName() ); SourceValue sourceValue = new SourceValue(); - HashMap map = new HashMap(); + HashMap map = new HashMap<>(); map.put( sourceKey, sourceValue ); source.setMap( map ); - Issue513Mapper.INSTANCE.map( source ); + assertThatThrownBy( () -> Issue513Mapper.INSTANCE.map( source ) ) + .isInstanceOf( MappingKeyException.class ); } - @Test( expected = MappingValueException.class ) + @ProcessorTest public void shouldThrowMappingValueException() throws Exception { Source source = new Source(); SourceKey sourceKey = new SourceKey(); SourceValue sourceValue = new SourceValue(); sourceValue.setValue( MappingValueException.class.getSimpleName() ); - HashMap map = new HashMap(); + HashMap map = new HashMap<>(); map.put( sourceKey, sourceValue ); source.setMap( map ); - Issue513Mapper.INSTANCE.map( source ); + assertThatThrownBy( () -> Issue513Mapper.INSTANCE.map( source ) ) + .isInstanceOf( MappingValueException.class ); } - @Test( expected = MappingException.class ) + @ProcessorTest public void shouldThrowMappingCommonException() throws Exception { Source source = new Source(); SourceKey sourceKey = new SourceKey(); SourceValue sourceValue = new SourceValue(); sourceValue.setValue( MappingException.class.getSimpleName() ); - HashMap map = new HashMap(); + HashMap map = new HashMap<>(); map.put( sourceKey, sourceValue ); source.setMap( map ); - Issue513Mapper.INSTANCE.map( source ); + assertThatThrownBy( () -> Issue513Mapper.INSTANCE.map( source ) ) + .isInstanceOf( MappingException.class ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingException.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingException.java index 2bf8c94730..289e86abbd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingKeyException.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingKeyException.java index af409b1d49..668667fb07 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingKeyException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingKeyException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingValueException.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingValueException.java index 0f536f647d..9bf51c2fdd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingValueException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/MappingValueException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Source.java index 963f63e755..1e85ffe808 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceElement.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceElement.java index 520261e0d6..329b502361 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceElement.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceElement.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceKey.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceKey.java index 40e691e207..9490e95d61 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceKey.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceKey.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceValue.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceValue.java index 84c38938c9..fbdde5a474 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceValue.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/SourceValue.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Target.java index ed289ef7ae..7356849403 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetElement.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetElement.java index 5dd5b081d9..532c44052b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetElement.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetElement.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetKey.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetKey.java index e06194dfd5..aef8b8ece1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetKey.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetKey.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetValue.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetValue.java index dbfb005017..beda1c1389 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetValue.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_513/TargetValue.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._513; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Mapper.java index a753c3720d..5baaa475d1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._515; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Test.java index 26e90117a8..eb32a41a85 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Issue515Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._515; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/515. @@ -30,10 +15,9 @@ * @author Sjaak Derksen */ @IssueKey( "515" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue515Test { - @Test + @ProcessorTest @WithClasses( { Issue515Mapper.class, Source.class, Target.class } ) public void shouldIgnoreParanthesesOpenInStringDefinition() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Source.java index bf269841bc..c21d940f63 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._515; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Target.java index ef6379de41..bfb27f7276 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_515/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._515; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Issue516Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Issue516Test.java index 862151774b..226a7f8157 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Issue516Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Issue516Test.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._516; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/516. @@ -32,10 +17,9 @@ * @author Sjaak Derksen */ @IssueKey( "516" ) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue516Test { - @Test + @ProcessorTest @WithClasses( { SourceTargetMapper.class, Source.class, Target.class } ) public void shouldAddNullPtrCheckAroundSourceForAdder() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Source.java index 7507117635..593522d4a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._516; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/SourceTargetMapper.java index 2e5c58cdd1..788ed39c89 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._516; @@ -22,7 +9,6 @@ import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Target.java index 76b42f4539..1b65b0662b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_516/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._516; @@ -39,7 +26,7 @@ public void setElements(List elements) { public void addElement(String element) { if ( elements == null ) { - elements = new ArrayList(); + elements = new ArrayList<>(); } elements.add( element ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Mapper.java index 67a88ba368..3651d41ba6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._537; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537MapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537MapperConfig.java index 21c81318e2..14a60f7b36 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537MapperConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537MapperConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._537; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Test.java index 22d9d39135..6d60aaa79e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Issue537Test.java @@ -1,35 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._537; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Christian Bandowski */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("537") @WithClasses({ Issue537Mapper.class, @@ -40,7 +24,7 @@ }) public class Issue537Test { - @Test + @ProcessorTest public void testThatReferencedMapperWillBeUsed() { Target target = Issue537Mapper.INSTANCE.mapDto( new Source( "abc" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/ReferenceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/ReferenceMapper.java index db3b91f924..86f9554c86 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/ReferenceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/ReferenceMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._537; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Source.java index 753c6a47c4..dd1040dafb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._537; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Target.java index afe1fb35b5..4a95e4aeed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_537/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._537; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Mapper.java index 798870ced7..1a22879c38 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._543; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Test.java index 2626dd4934..4a6f0176d1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/Issue543Test.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._543; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.bugs._543.dto.Source; import org.mapstruct.ap.test.bugs._543.dto.Target; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("543") @WithClasses({ Issue543Mapper.class, @@ -41,10 +25,10 @@ }) public class Issue543Test { - @Rule - public GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest public void shouldCompile() { generatedSource.forMapper( Issue543Mapper.class ).containsImportFor( Source.class ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/SourceUtil.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/SourceUtil.java index 7c5808fb87..ef0e7879e4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/SourceUtil.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/SourceUtil.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._543; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Source.java index 1c6148d5f0..2a996f1fe9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._543.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Target.java index 25a423db9b..c868716db6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_543/dto/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._543.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Issue577Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Issue577Test.java index 74191a4a22..198231f410 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Issue577Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Issue577Test.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._577; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @IssueKey( "577" ) @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue577Test { - @Test + @ProcessorTest public void shouldMapTwoArraysToCollections() { Source source = new Source(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Source.java index c5aec85321..80dd1d6408 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._577; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/SourceTargetMapper.java index 784151666a..7b4987c996 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._577; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Target.java index b59022e87a..7646439a66 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_577/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._577; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/Issue581Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/Issue581Test.java index f557a7a797..7c1dfb266e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/Issue581Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/Issue581Test.java @@ -1,38 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._581; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._581.source.Car; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @IssueKey( "581" ) @WithClasses({ Car.class, org.mapstruct.ap.test.bugs._581._target.Car.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue581Test { - @Test + @ProcessorTest public void shouldMapSourceAndTargetWithTheSameClassName() { Car source = new Car(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/SourceTargetMapper.java index 02234dc553..4619412738 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._581; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/_target/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/_target/Car.java index 9ac3649ae7..cf472286b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/_target/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/_target/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._581._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/source/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/source/Car.java index cef6c41d1a..b5289a3492 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/source/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_581/source/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._581.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/ErroneousSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/ErroneousSourceTargetMapper.java index 8300bf971a..0991468293 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/ErroneousSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/ErroneousSourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._590; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java index ef7091bc69..0bf8553e15 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_590/Issue590Test.java @@ -1,45 +1,32 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._590; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(ErroneousSourceTargetMapper.class) public class Issue590Test { - @Test + @ProcessorTest @ExpectedCompilationOutcome(value = CompilationResult.FAILED, - diagnostics = { @Diagnostic(type = ErroneousSourceTargetMapper.class, - kind = Kind.ERROR, - messageRegExp = "Can't map property \"java\\.lang\\.String prop\" to \"[^ ]+ prop\"") }) + diagnostics = { + @Diagnostic(type = ErroneousSourceTargetMapper.class, + kind = Kind.ERROR, + message = "Can't map property \"String prop\" to \"XMLFormatter prop\". " + + "Consider to declare/implement a mapping method: \"XMLFormatter map(String value)\".") + }) public void showsCantMapPropertyError() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/Issue611Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/Issue611Test.java index f8e96ec75d..b77da90ad9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/Issue611Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/Issue611Test.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._611; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -30,7 +15,6 @@ * @author Tillmann Gaida */ @IssueKey("611") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ SomeClass.class, SomeOtherClass.class @@ -39,7 +23,7 @@ public class Issue611Test { /** * Checks if an implementation of a nested mapper can be loaded at all. */ - @Test + @ProcessorTest public void mapperIsFound() { assertThat( SomeClass.InnerMapper.INSTANCE ).isNotNull(); } @@ -48,7 +32,7 @@ public void mapperIsFound() { * Checks if an implementation of a nested mapper can be loaded which is nested into an already * nested class. */ - @Test + @ProcessorTest public void mapperNestedInsideNestedClassIsFound() { assertThat( SomeClass.SomeInnerClass.InnerMapper.INSTANCE ).isNotNull(); } @@ -57,10 +41,10 @@ public void mapperNestedInsideNestedClassIsFound() { * Checks if it is possible to load two mapper implementations which have equal simple names * in the same package. */ - @Test + @ProcessorTest public void rightMapperIsFound() { - SomeClass.InnerMapper.Source source1 = new SomeClass.InnerMapper.Source(); - SomeOtherClass.InnerMapper.Source source2 = new SomeOtherClass.InnerMapper.Source(); + SomeClass.InnerMapper.Source source1 = new SomeClass.InnerMapper.Source( "test" ); + SomeOtherClass.InnerMapper.Source source2 = new SomeOtherClass.InnerMapper.Source( "test2" ); SomeClass.InnerMapper.Target target1 = SomeClass.InnerMapper.INSTANCE.toTarget( source1 ); SomeOtherClass.InnerMapper.Target target2 = SomeOtherClass.InnerMapper.INSTANCE.toTarget( source2 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeClass.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeClass.java index ea9bd23f9f..e0fb59d4d7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeClass.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeClass.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._611; @@ -32,9 +19,29 @@ public interface InnerMapper { Target toTarget(Source in); class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } } class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } } } @@ -46,9 +53,29 @@ public interface InnerMapper { Target toTarget(Source in); class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } } class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } } } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeOtherClass.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeOtherClass.java index aa0c560027..2ff2d0d831 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeOtherClass.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_611/SomeOtherClass.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._611; @@ -32,9 +19,29 @@ public interface InnerMapper { Target toTarget(Source in); class Source { + + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } } class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } } } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Issue625Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Issue625Test.java index f52dac5d29..81ff528da5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Issue625Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Issue625Test.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._625; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Andreas Gudian * */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ ObjectFactory.class, Source.class, @@ -40,7 +24,7 @@ }) @IssueKey("625") public class Issue625Test { - @Test + @ProcessorTest public void ignoresFactoryMethods() { Source s = new Source(); s.setProp( "works" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/ObjectFactory.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/ObjectFactory.java index a4fdbca8bb..3cdf4a03df 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/ObjectFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/ObjectFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._625; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Source.java index 64fd2df40b..94a811a0f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._625; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/SourceTargetMapper.java index af4650cab8..e11cb05411 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._625; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Target.java index bfa7af20da..2340f7e09e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_625/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._625; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base1.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base1.java index cfaf8fecd9..eccc9fb612 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base1.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base1.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._631; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base2.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base2.java index 7b9fd40a62..3e01907520 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Base2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._631; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/ErroneousSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/ErroneousSourceTargetMapper.java index 5f2a91314b..30e4688b8c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/ErroneousSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/ErroneousSourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._631; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Issue631Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Issue631Test.java index 2dac1dd640..57a221c6d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Issue631Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_631/Issue631Test.java @@ -1,53 +1,37 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._631; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) public class Issue631Test { - @Test + @ProcessorTest @IssueKey("631") @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousSourceTargetMapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "Can't generate mapping method for a generic type variable target."), + line = 22, + message = "Can't generate mapping method for a generic type variable target."), @Diagnostic(type = ErroneousSourceTargetMapper.class, kind = Kind.ERROR, - line = 37, - messageRegExp = "Can't generate mapping method for a generic type variable source.") + line = 24, + message = "Can't generate mapping method for a generic type variable source.") } ) @WithClasses({ErroneousSourceTargetMapper.class, Base1.class, Base2.class}) diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Bar.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Bar.java index 4e4b84e5a4..c731414aa6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Bar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Bar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._634; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Foo.java index ebb28d7533..10ba1b423e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._634; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/GenericContainerTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/GenericContainerTest.java index 551982b558..99d609408e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/GenericContainerTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/GenericContainerTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._634; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Gunnar Morling @@ -39,14 +24,13 @@ Target.class, SourceTargetMapper.class, }) -@RunWith(AnnotationProcessorTestRunner.class) public class GenericContainerTest { - @Test + @ProcessorTest @IssueKey("634") public void canMapGenericSourceTypeToGenericTargetType() { List items = Arrays.asList( new Foo( "42" ), new Foo( "84" ) ); - Source source = new Source( items ); + Source source = new Source<>( items ); Target target = SourceTargetMapper.INSTANCE.mapSourceToTarget( source ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Source.java index 895effb2c2..e5d3ae101b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._634; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/SourceTargetMapper.java index f465934d45..54bb1a2651 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._634; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Target.java index a368b2e673..5c3a1cb892 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_634/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._634; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableContainer.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableContainer.java index 472e340747..ed2d0df612 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableContainer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableContainer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._775; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableWithBoundedElementTypeTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableWithBoundedElementTypeTest.java index 0e4e26f7ac..db2f376416 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableWithBoundedElementTypeTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/IterableWithBoundedElementTypeTest.java @@ -1,32 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._775; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.assertj.core.api.IterableAssert; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Verifies: @@ -38,7 +24,6 @@ * * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("775") @WithClasses({ MapperWithForgedIterableMapping.class, @@ -48,23 +33,25 @@ }) public class IterableWithBoundedElementTypeTest { - @Test + @ProcessorTest public void createsForgedMethodForIterableLowerBoundInteger() { ListContainer source = new ListContainer(); source.setValues( Arrays.asList( "42", "47" ) ); IterableContainer result = MapperWithForgedIterableMapping.INSTANCE.toContainerWithIterable( source ); - assertThat( result.getValues() ).contains( Integer.valueOf( 42 ), Integer.valueOf( 47 ) ); + ( (IterableAssert) assertThat( result.getValues() ) ) + .contains( 42, 47 ); } - @Test + @ProcessorTest public void usesListIntegerMethodForIterableLowerBoundInteger() { ListContainer source = new ListContainer(); source.setValues( Arrays.asList( "42", "47" ) ); IterableContainer result = MapperWithCustomListMapping.INSTANCE.toContainerWithIterable( source ); - assertThat( result.getValues() ).contains( Integer.valueOf( 66 ), Integer.valueOf( 71 ) ); + ( (IterableAssert) assertThat( result.getValues() ) ) + .contains( 66, 71 ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/ListContainer.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/ListContainer.java index df520075e3..77a5303196 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/ListContainer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/ListContainer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._775; @@ -25,7 +12,7 @@ * @author Andreas Gudian */ public class ListContainer { - private List values = new ArrayList(); + private List values = new ArrayList<>(); public List getValues() { return values; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithCustomListMapping.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithCustomListMapping.java index 1c6cdc8249..dba7dc2360 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithCustomListMapping.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithCustomListMapping.java @@ -1,26 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._775; -import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -36,11 +23,8 @@ public abstract class MapperWithCustomListMapping { public abstract IterableContainer toContainerWithIterable(ListContainer source); protected List hexListToIntList(Collection source) { - List iterable = new ArrayList( source.size() ); - for ( String string : source ) { - iterable.add( Integer.parseInt( string, 16 ) ); - } - - return iterable; + return source.stream() + .map( string -> Integer.parseInt( string, 16 ) ) + .collect( Collectors.toList() ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithForgedIterableMapping.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithForgedIterableMapping.java index 473f5b93da..c659bf596c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithForgedIterableMapping.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_775/MapperWithForgedIterableMapping.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._775; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Commit.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Commit.java index b47f65f49f..431a999c45 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Commit.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Commit.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._843; @@ -43,4 +30,8 @@ public static int getCallCounter() { return callCounter; } + public static void resetCallCounter() { + callCounter = 0; + } + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/GitlabTag.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/GitlabTag.java index 922a94e08b..28df16ee08 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/GitlabTag.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/GitlabTag.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._843; @@ -41,4 +28,8 @@ public static int getCallCounter() { return callCounter; } + public static void resetCallCounter() { + callCounter = 0; + } + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Issue843Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Issue843Test.java index c8d4c48a28..4937f6c3d4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Issue843Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/Issue843Test.java @@ -1,38 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._843; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Date; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Commit.class, TagInfo.class, @@ -42,7 +26,7 @@ @IssueKey("843") public class Issue843Test { - @Test + @ProcessorTest public void testMapperCreation() { Commit commit = new Commit(); @@ -50,6 +34,8 @@ public void testMapperCreation() { GitlabTag gitlabTag = new GitlabTag(); gitlabTag.setCommit( commit ); + Commit.resetCallCounter(); + GitlabTag.resetCallCounter(); TagMapper.INSTANCE.gitlabTagToTagInfo( gitlabTag ); assertThat( Commit.getCallCounter() ).isEqualTo( 1 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagInfo.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagInfo.java index 5870853ca9..55af1beb9d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagInfo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagInfo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._843; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagMapper.java index 5e6d20b1c9..334ac52ef0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_843/TagMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._843; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/Mapper846.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/Mapper846.java index 1747c94be3..5ce79afa03 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/Mapper846.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/Mapper846.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._846; @@ -69,7 +56,7 @@ public void setaName(String name) { @Mapper interface MyMapper { - @Mapping(source = "name", target = "aName") + @Mapping(target = "aName", source = "name") A convert(BInterface b); @InheritInverseConfiguration diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/UpdateTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/UpdateTest.java index 63aa45a874..776f3f70e0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/UpdateTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_846/UpdateTest.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._846; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("846") @WithClasses({ Mapper846.class }) public class UpdateTest { - @Test + @ProcessorTest public void shouldProduceMapper() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Mapper.java index 0b08571599..2891971dfd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._849; @@ -31,7 +18,7 @@ public interface Issue849Mapper { Issue849Mapper INSTANCE = Mappers.getMapper( Issue849Mapper.class ); - @Mapping(source = "sourceList", target = "targetList") + @Mapping(target = "targetList", source = "sourceList") Target mapSourceToTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Test.java index 224b0306d7..22ec5bd309 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Issue849Test.java @@ -1,48 +1,31 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._849; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.Serializable; import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian * */ @WithClasses({ Source.class, Target.class, Issue849Mapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class Issue849Test { - @Test + @ProcessorTest @IssueKey("849") public void shouldCompileWithAllImportsDeclared() { Source source = new Source(); - source.setSourceList( Arrays.asList( (Serializable) "test" ) ); + source.setSourceList( Arrays.asList( "test" ) ); Target target = Issue849Mapper.INSTANCE.mapSourceToTarget( source ); assertThat( target.getTargetList() ).containsExactly( "test" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Source.java index 064ffe5b14..f96483aa24 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._849; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Target.java index 0618b10bb1..8bd9e9d17b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_849/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._849; @@ -32,7 +19,7 @@ public class Target { public List getTargetList() { if ( targetList == null ) { - targetList = new ArrayList(); + targetList = new ArrayList<>(); } return targetList; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderDemoMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderDemoMapper.java index 5f0062aaf7..f968509d65 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderDemoMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderDemoMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._855; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedSource.java index f96ca6ef08..6cc57147a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._855; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedTarget.java index 4f35b13ca6..10e89795b2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderedTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._855; @@ -25,7 +12,7 @@ * @author Markus Heberling */ class OrderedTarget { - private List order = new LinkedList(); + private List order = new LinkedList<>(); public void setField0(String field0) { order.add( "field0" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderingBug855Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderingBug855Test.java index 2729eca1cd..54ee84a89c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderingBug855Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_855/OrderingBug855Test.java @@ -1,40 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._855; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian * */ @WithClasses({ OrderedSource.class, OrderedTarget.class, OrderDemoMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class OrderingBug855Test { - @Test + @ProcessorTest @IssueKey("855") public void shouldApplyCorrectOrderingWithDependsOn() { OrderedSource source = new OrderedSource(); @@ -44,7 +28,7 @@ public void shouldApplyCorrectOrderingWithDependsOn() { assertThat( target.getOrder() ).containsExactly( "field2", "field0", "field1", "field3", "field4" ); } - @Test + @ProcessorTest public void shouldRetainDefaultOrderWithoutDependsOn() { OrderedSource source = new OrderedSource(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/Issue865Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/Issue865Test.java index 8871f6dc1f..f5196ec7b7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/Issue865Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/Issue865Test.java @@ -1,34 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; -import static org.assertj.core.api.Assertions.assertThat; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses( { ProjectDto.class, ProjectEntity.class, @@ -39,8 +24,8 @@ } ) public class Issue865Test { - @Test - public void shouldGenerateNpeCheckBeforCallingAddAllWhenInUpdateMethods() { + @ProcessorTest + public void shouldGenerateNpeCheckBeforeCallingAddAllWhenInUpdateMethods() { ProjectDto dto = new ProjectDto(); dto.setName( "myProject" ); @@ -54,7 +39,8 @@ public void shouldGenerateNpeCheckBeforCallingAddAllWhenInUpdateMethods() { assertThat( entity.getCoreUsers() ).isNull(); } - public void shouldGenerateNpeCheckBeforCallingAddAllWhenInUpdateMethodsAndTargetWithoutSetter() { + @ProcessorTest + public void shouldGenerateNpeCheckBeforeCallingAddAllWhenInUpdateMethodsAndTargetWithoutSetter() { ProjectDto dto = new ProjectDto(); dto.setName( "myProject" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjCoreUserEntity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjCoreUserEntity.java index d1865e6873..ee6495f568 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjCoreUserEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjCoreUserEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjMemberDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjMemberDto.java index 0f97e62f3a..ada4fdc40d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjMemberDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjMemberDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectDto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectDto.java index de288c29ca..1bd35bae76 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntity.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntity.java index e57b95acf9..dd01abe045 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntityWithoutSetter.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntityWithoutSetter.java index 691fdcc432..8e4ae71129 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntityWithoutSetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectEntityWithoutSetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectMapper.java index ffa699adb8..b23db3d35d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_865/ProjectMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._865; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Config.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Config.java deleted file mode 100644 index cf50a0a392..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Config.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._880; - -import org.mapstruct.MapperConfig; -import org.mapstruct.ReportingPolicy; - -/** - * @author Andreas Gudian - */ -@MapperConfig(unmappedTargetPolicy = ReportingPolicy.WARN) -public interface Config { - -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/DefaultsToProcessorOptionsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/DefaultsToProcessorOptionsMapper.java deleted file mode 100644 index d1555374ca..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/DefaultsToProcessorOptionsMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._880; - -import org.mapstruct.Mapper; - -/** - * @author Andreas Gudian - * - */ -@Mapper -public interface DefaultsToProcessorOptionsMapper { - Poodle metamorph(Object essence); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Issue880Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Issue880Test.java deleted file mode 100644 index b3db6c142e..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Issue880Test.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._880; - -import javax.tools.Diagnostic.Kind; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; -import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; -import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; -import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOptions; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -import org.mapstruct.ap.testutil.runner.GeneratedSource; -import org.springframework.stereotype.Component; - -/** - * @author Andreas Gudian - */ -@RunWith(AnnotationProcessorTestRunner.class) -@WithClasses({ - UsesConfigFromAnnotationMapper.class, - DefaultsToProcessorOptionsMapper.class, - Poodle.class, - Config.class }) -@ProcessorOptions({ - @ProcessorOption(name = "mapstruct.defaultComponentModel", value = "spring"), - @ProcessorOption(name = "mapstruct.unmappedTargetPolicy", value = "ignore") }) -public class Issue880Test { - @Rule - public GeneratedSource generatedSource = new GeneratedSource(); - - @Test - @ExpectedCompilationOutcome( - value = CompilationResult.SUCCEEDED, - diagnostics = @Diagnostic(kind = Kind.WARNING, - type = UsesConfigFromAnnotationMapper.class, line = 29, - messageRegExp = "Unmapped target property: \"core\"\\.")) - public void compilationSucceedsAndAppliesCorrectComponentModel() { - generatedSource.forMapper( UsesConfigFromAnnotationMapper.class ).containsNoImportFor( Component.class ); - - generatedSource.forMapper( DefaultsToProcessorOptionsMapper.class ).containsImportFor( Component.class ); - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Poodle.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Poodle.java deleted file mode 100644 index 5974d6d4df..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/Poodle.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._880; - -/** - * @author Andreas Gudian - * - */ -public class Poodle { - private String core; - - public String getCore() { - return core; - } - - public void setCore(String core) { - this.core = core; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/UsesConfigFromAnnotationMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/UsesConfigFromAnnotationMapper.java deleted file mode 100644 index 72e7d57847..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/UsesConfigFromAnnotationMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.bugs._880; - -import org.mapstruct.Mapper; - -/** - * @author Andreas Gudian - * - */ -@Mapper(componentModel = "default", config = Config.class) -public interface UsesConfigFromAnnotationMapper { - Poodle metamorph(Object essence); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Config.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Config.java new file mode 100644 index 0000000000..7aef1e9e1f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Config.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._880.spring; + +import org.mapstruct.MapperConfig; +import org.mapstruct.ReportingPolicy; + +/** + * @author Andreas Gudian + */ +@MapperConfig(unmappedTargetPolicy = ReportingPolicy.WARN) +public interface Config { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/DefaultsToProcessorOptionsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/DefaultsToProcessorOptionsMapper.java new file mode 100644 index 0000000000..5f67b41552 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/DefaultsToProcessorOptionsMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._880.spring; + +import org.mapstruct.Mapper; + +/** + * @author Andreas Gudian + * + */ +@Mapper +public interface DefaultsToProcessorOptionsMapper { + Poodle metamorph(Object essence); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Issue880Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Issue880Test.java new file mode 100644 index 0000000000..cd85829147 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Issue880Test.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._880.spring; + +import javax.tools.Diagnostic.Kind; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOptions; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.stereotype.Component; + +/** + * @author Andreas Gudian + */ +@WithClasses({ + UsesConfigFromAnnotationMapper.class, + DefaultsToProcessorOptionsMapper.class, + Poodle.class, + Config.class }) +@ProcessorOptions({ + @ProcessorOption(name = "mapstruct.defaultComponentModel", value = MappingConstants.ComponentModel.SPRING), + @ProcessorOption(name = "mapstruct.unmappedTargetPolicy", value = "ignore") }) +@WithSpring +public class Issue880Test { + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = @Diagnostic(kind = Kind.WARNING, + type = UsesConfigFromAnnotationMapper.class, line = 17, + message = "Unmapped target property: \"core\".")) + public void compilationSucceedsAndAppliesCorrectComponentModel() { + generatedSource.forMapper( UsesConfigFromAnnotationMapper.class ).containsNoImportFor( Component.class ); + + generatedSource.forMapper( DefaultsToProcessorOptionsMapper.class ).containsImportFor( Component.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Poodle.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Poodle.java new file mode 100644 index 0000000000..71166f6d4c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/Poodle.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._880.spring; + +/** + * @author Andreas Gudian + * + */ +public class Poodle { + private String core; + + public String getCore() { + return core; + } + + public void setCore(String core) { + this.core = core; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/UsesConfigFromAnnotationMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/UsesConfigFromAnnotationMapper.java new file mode 100644 index 0000000000..bb9a7def9f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_880/spring/UsesConfigFromAnnotationMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._880.spring; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; + +/** + * @author Andreas Gudian + * + */ +@Mapper(componentModel = MappingConstants.ComponentModel.DEFAULT, config = Config.class) +public interface UsesConfigFromAnnotationMapper { + Poodle metamorph(Object essence); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/BuggyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/BuggyMapper.java index 1d39b11be6..fbb9fcd6c9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/BuggyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/BuggyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._891; @@ -31,6 +18,6 @@ public interface BuggyMapper { BuggyMapper INSTANCE = Mappers.getMapper( BuggyMapper.class ); - @Mapping(source = "nested.propInt", target = "propLong") + @Mapping(target = "propLong", source = "nested.propInt") Dest convert(Src src); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Dest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Dest.java index 281c065ef8..f0a8c64936 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Dest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Dest.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._891; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Issue891Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Issue891Test.java index 78ab232aeb..5fae478f2e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Issue891Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Issue891Test.java @@ -1,36 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._891; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({BuggyMapper.class, Dest.class, Src.class, SrcNested.class}) public class Issue891Test { - @Test + @ProcessorTest public void shouldNotThrowNPE() { BuggyMapper.INSTANCE.convert( new Src() ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Src.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Src.java index 3e65efab4f..f461aba664 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Src.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/Src.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._891; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/SrcNested.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/SrcNested.java index c638f9d263..5557030822 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/SrcNested.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_891/SrcNested.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._891; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Mapper.java index f53762ecf8..84b6d12a15 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._892; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Test.java index 3bdb375eeb..0064a96338 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_892/Issue892Test.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._892; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._892.Issue892Mapper.Source; import org.mapstruct.ap.test.bugs._892.Issue892Mapper.Target; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** * When having two setter methods with the same name, choose the one with the argument type matching the getter method. * * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Issue892Mapper.class }) public class Issue892Test { - @Test + @ProcessorTest public void compiles() { Source src = new Source(); src.setType( 42 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/Issue895Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/Issue895Test.java index 1cafeaa3d9..6250e139f2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/Issue895Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/Issue895Test.java @@ -1,42 +1,30 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._895; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._895.MultiArrayMapper.WithArrayOfByteArray; +import org.mapstruct.ap.test.bugs._895.MultiArrayMapper.WithArrayOfGenericArray; import org.mapstruct.ap.test.bugs._895.MultiArrayMapper.WithListOfByteArray; +import org.mapstruct.ap.test.bugs._895.MultiArrayMapper.WithListOfGenericArray; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** - * Verifies that forged iterable mapping methods for multi-dimensional arrays are generated properly. + * Verifies that forged iterable mapping methods for multidimensional arrays are generated properly. * * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) +@IssueKey("895") @WithClasses(MultiArrayMapper.class) public class Issue895Test { - @Test + @ProcessorTest public void properlyMapsMultiDimensionalArrays() { WithArrayOfByteArray arrayOfByteArray = new WithArrayOfByteArray(); arrayOfByteArray.setBytes( new byte[][] { new byte[] { 0, 1 }, new byte[] { 1, 2 } } ); @@ -45,6 +33,44 @@ public void properlyMapsMultiDimensionalArrays() { assertThat( listOfByteArray.getBytes() ).containsExactly( new byte[] { 0, 1 }, new byte[] { 1, 2 } ); arrayOfByteArray = Mappers.getMapper( MultiArrayMapper.class ).convert( listOfByteArray ); - assertThat( arrayOfByteArray.getBytes() ).containsExactly( new byte[] { 0, 1 }, new byte[] { 1, 2 } ); + assertThat( arrayOfByteArray.getBytes() ).isDeepEqualTo( new byte[][] { { 0, 1 }, { 1, 2 } } ); + } + + @ProcessorTest + public void properlyMapsGenericMultiDimensionalArrays() { + WithArrayOfGenericArray arrayOfStringArray = new MultiArrayMapper.WithArrayOfGenericArray<>(); + arrayOfStringArray.setData( new String[][] { new String[] { "a", "b" }, new String[] { "b", "c" } } ); + + MultiArrayMapper mapper = Mappers.getMapper( MultiArrayMapper.class ); + WithListOfGenericArray listOfStringArray = mapper.convertGeneric( arrayOfStringArray ); + assertThat( listOfStringArray.getData() ) + .containsExactly( new String[] { "a", "b" }, new String[] { "b", "c" } ); + + arrayOfStringArray = mapper.convertGeneric( listOfStringArray ); + assertThat( arrayOfStringArray.getData() ) + .isDeepEqualTo( new String[][] { new String[] { "a", "b" }, new String[] { "b", "c" } } ); + } + + @ProcessorTest + public void properlyReturnDefaultForMultiArray() { + assertThat( Mappers.getMapper( MultiArrayMapper.class ).copyMultiArray( null ) ).isEmpty(); + } + + @ProcessorTest + @SuppressWarnings("unchecked") + public void properlyMapsGenericMultiArray() { + WithArrayOfGenericArray arrayOfGenericArray = new WithArrayOfGenericArray<>(); + arrayOfGenericArray.setData( new String[][] { new String[] { "a", "b" }, new String[] { "b", "c" } } ); + WithArrayOfGenericArray[][] multiArrayOfGenericArray = + new WithArrayOfGenericArray[][]{ new WithArrayOfGenericArray[]{ arrayOfGenericArray } }; + WithArrayOfGenericArray[][] result = + Mappers.getMapper( MultiArrayMapper.class ).copyGenericMultiArray( multiArrayOfGenericArray ); + assertThat( result ).isNotSameAs( multiArrayOfGenericArray ); + assertThat( result ).isDeepEqualTo( multiArrayOfGenericArray ); + } + + @ProcessorTest + public void properlyReturnDefaultForGenericMultiArray() { + assertThat( Mappers.getMapper( MultiArrayMapper.class ).copyGenericMultiArray( null ) ).isEmpty(); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/MultiArrayMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/MultiArrayMapper.java index 4acc5b6e7a..13a67125b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/MultiArrayMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_895/MultiArrayMapper.java @@ -1,26 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._895; import java.util.List; +import org.mapstruct.IterableMapping; import org.mapstruct.Mapper; +import org.mapstruct.NullValueMappingStrategy; /** * @author Andreas Gudian @@ -43,6 +32,16 @@ public void setBytes(byte[][] bytes) { } } + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) + int[][] copyMultiArray(int[][] multiArray); + + WithListOfGenericArray convertGeneric(WithArrayOfGenericArray b); + + WithArrayOfGenericArray convertGeneric(WithListOfGenericArray b); + + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) + WithArrayOfGenericArray[][] copyGenericMultiArray(WithArrayOfGenericArray[][] multiArray); + class WithListOfByteArray { private List bytes; @@ -54,4 +53,28 @@ public void setBytes(List bytes) { this.bytes = bytes; } } + + class WithArrayOfGenericArray { + private T [][] data; + + public T[][] getData() { + return data; + } + + public void setData(T[][] data) { + this.data = data; + } + } + + class WithListOfGenericArray { + private List data; + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/Issue909Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/Issue909Test.java index 4cbe2531f0..20710488f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/Issue909Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/Issue909Test.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._909; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._909.ValuesMapper.ValuesHolder; import org.mapstruct.ap.test.bugs._909.ValuesMapper.ValuesHolderDto; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; + /** * Verifies that forged iterable mapping methods for multi-dimensional arrays are generated properly. * * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses(ValuesMapper.class) public class Issue909Test { - @Test + @ProcessorTest public void properlyCreatesMapperWithValuesAsParameterName() { ValuesHolder valuesHolder = new ValuesHolder(); valuesHolder.setValues( "values" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/ValuesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/ValuesMapper.java index 2061e8d51f..fb4cede674 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/ValuesMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_909/ValuesMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._909; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Domain.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Domain.java index 022a937c95..500adf3066 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Domain.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Domain.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; @@ -27,8 +14,8 @@ * @author Sjaak Derksen */ public class Domain { - static final Set DEFAULT_STRINGS = new HashSet(); - static final Set DEFAULT_LONGS = new HashSet(); + static final Set DEFAULT_STRINGS = new HashSet<>(); + static final Set DEFAULT_LONGS = new HashSet<>(); private Set strings = DEFAULT_STRINGS; private Set longs = DEFAULT_LONGS; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNcvsAlwaysMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNcvsAlwaysMapper.java index 4ce109c9f0..11be515838 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNcvsAlwaysMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNcvsAlwaysMapper.java @@ -1,29 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; +import org.mapstruct.BeanMapping; import org.mapstruct.InheritConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; +import org.mapstruct.Named; import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ObjectFactory; import org.mapstruct.factory.Mappers; /** @@ -35,6 +25,7 @@ public interface DomainDtoWithNcvsAlwaysMapper { DomainDtoWithNcvsAlwaysMapper INSTANCE = Mappers.getMapper( DomainDtoWithNcvsAlwaysMapper.class ); + @BeanMapping( qualifiedByName = "DomainObjectFactory" ) @Mappings({ @Mapping(target = "strings", source = "strings"), @Mapping(target = "longs", source = "strings"), @@ -49,4 +40,13 @@ public interface DomainDtoWithNcvsAlwaysMapper { @InheritConfiguration( name = "create" ) Domain updateWithReturn(DtoWithPresenceCheck source, @MappingTarget Domain target); + + @ObjectFactory + @Named( "DomainObjectFactory" ) + default Domain createNullDomain() { + Domain domain = new Domain(); + domain.setLongs( null ); + domain.setStrings( null ); + return domain; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsDefaultMapper.java index e926b2c920..7cd3cfedef 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsDefaultMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsDefaultMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; @@ -24,13 +11,17 @@ import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.factory.Mappers; /** * * @author Sjaak Derksen */ -@Mapper( nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, uses = Helper.class ) +@Mapper( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT, + uses = Helper.class ) public interface DomainDtoWithNvmsDefaultMapper { DomainDtoWithNvmsDefaultMapper INSTANCE = Mappers.getMapper( DomainDtoWithNvmsDefaultMapper.class ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsNullMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsNullMapper.java index c7a6a3d8ad..d288b666f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsNullMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithNvmsNullMapper.java @@ -1,28 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; +import org.mapstruct.BeanMapping; import org.mapstruct.InheritConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; +import org.mapstruct.Named; +import org.mapstruct.ObjectFactory; import org.mapstruct.factory.Mappers; /** @@ -35,6 +25,7 @@ public interface DomainDtoWithNvmsNullMapper { DomainDtoWithNvmsNullMapper INSTANCE = Mappers.getMapper( DomainDtoWithNvmsNullMapper.class ); + @BeanMapping( qualifiedByName = "DomainObjectFactory" ) @Mappings({ @Mapping(target = "strings", source = "strings"), @Mapping(target = "longs", source = "strings"), @@ -49,4 +40,13 @@ public interface DomainDtoWithNvmsNullMapper { @InheritConfiguration( name = "create" ) Domain updateWithReturn(Dto source, @MappingTarget Domain target); + + @ObjectFactory + @Named( "DomainObjectFactory" ) + default Domain createNullDomain() { + Domain domain = new Domain(); + domain.setLongs( null ); + domain.setStrings( null ); + return domain; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithPresenceCheckMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithPresenceCheckMapper.java index 1675a74058..83b8539a41 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithPresenceCheckMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainDtoWithPresenceCheckMapper.java @@ -1,28 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; +import org.mapstruct.BeanMapping; import org.mapstruct.InheritConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; +import org.mapstruct.Named; +import org.mapstruct.ObjectFactory; import org.mapstruct.factory.Mappers; /** @@ -35,6 +25,7 @@ public interface DomainDtoWithPresenceCheckMapper { DomainDtoWithPresenceCheckMapper INSTANCE = Mappers.getMapper( DomainDtoWithPresenceCheckMapper.class ); + @BeanMapping( qualifiedByName = "DomainObjectFactory" ) @Mappings({ @Mapping(target = "strings", source = "strings"), @Mapping(target = "longs", source = "strings"), @@ -49,4 +40,13 @@ public interface DomainDtoWithPresenceCheckMapper { @InheritConfiguration( name = "create" ) Domain updateWithReturn(DtoWithPresenceCheck source, @MappingTarget Domain target); + + @ObjectFactory + @Named( "DomainObjectFactory" ) + default Domain createNullDomain() { + Domain domain = new Domain(); + domain.setLongs( null ); + domain.setStrings( null ); + return domain; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetter.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetter.java index dc761eb277..a808d78737 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; @@ -29,11 +16,11 @@ */ public class DomainWithoutSetter { - private final Set strings = new HashSet(); - private final Set longs = new HashSet(); - private final Set stringsInitialized = new HashSet(); - private final Set longsInitialized = new HashSet(); - private final List stringsWithDefault = new ArrayList(); + private final Set strings = new HashSet<>(); + private final Set longs = new HashSet<>(); + private final Set stringsInitialized = new HashSet<>(); + private final Set longsInitialized = new HashSet<>(); + private final List stringsWithDefault = new ArrayList<>(); public Set getStrings() { return strings; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsDefaultMapper.java index de537096d1..74564f7859 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsDefaultMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsDefaultMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsNullMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsNullMapper.java index d6f595163d..90916555ae 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsNullMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithNvmsNullMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithPresenceCheckMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithPresenceCheckMapper.java index a5758ab8c1..b3ed59852c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithPresenceCheckMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DomainWithoutSetterDtoWithPresenceCheckMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Dto.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Dto.java index cbc01b8243..507180bc07 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Dto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Dto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; @@ -29,7 +16,7 @@ public class Dto { private List strings; - private List stringsInitialized = new ArrayList( Arrays.asList( "5" ) ); + private List stringsInitialized = new ArrayList<>( Arrays.asList( "5" ) ); private List stringsWithDefault; public List getStrings() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DtoWithPresenceCheck.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DtoWithPresenceCheck.java index a4a6103e4d..27c262da12 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DtoWithPresenceCheck.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/DtoWithPresenceCheck.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; @@ -29,7 +16,7 @@ public class DtoWithPresenceCheck { private List strings; - private List stringsInitialized = new ArrayList( Arrays.asList( "5" ) ); + private List stringsInitialized = new ArrayList<>( Arrays.asList( "5" ) ); private List stringsWithDefault; public boolean hasStrings() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Helper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Helper.java index 1e60807a28..91c8db655f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Helper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Helper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913GetterMapperForCollectionsTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913GetterMapperForCollectionsTest.java index 96ec3968f4..4e10a4895f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913GetterMapperForCollectionsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913GetterMapperForCollectionsTest.java @@ -1,29 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; -import static org.assertj.core.api.Assertions.assertThat; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * All these test cases test the possible combinations in the GetterMapperForCollections. @@ -32,7 +18,6 @@ * * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ DomainWithoutSetter.class, Dto.class, @@ -49,7 +34,7 @@ public class Issue913GetterMapperForCollectionsTest { * conversion from string to long that return null in the entire mapper, so also for the forged * mapper. Note the default NVMS is RETURN_NULL. */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForCreate() { Dto dto = new Dto(); @@ -65,7 +50,7 @@ public void shouldReturnNullForNvmsReturnNullForCreate() { * conversion from string to long that return null in the entire mapper, so also for the forged * mapper. Note the default NVMS is RETURN_NULL. */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForUpdate() { Dto dto = new Dto(); @@ -83,7 +68,7 @@ public void shouldReturnNullForNvmsReturnNullForUpdate() { * conversion from string to long that return null in the entire mapper, so also for the forged * mapper. Note the default NVMS is RETURN_NULL. */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForUpdateWithReturn() { Dto dto = new Dto(); @@ -105,7 +90,7 @@ public void shouldReturnNullForNvmsReturnNullForUpdateWithReturn() { * * However, for plain mappings (strings to strings) the result will be null. */ - @Test + @ProcessorTest public void shouldReturnDefaultForNvmsReturnDefaultForCreate() { Dto dto = new Dto(); @@ -123,7 +108,7 @@ public void shouldReturnDefaultForNvmsReturnDefaultForCreate() { * * However, for plain mappings (strings to strings) the result will be null. */ - @Test + @ProcessorTest public void shouldReturnDefaultForNvmsReturnDefaultForUpdate() { Dto dto = new Dto(); @@ -144,7 +129,7 @@ public void shouldReturnDefaultForNvmsReturnDefaultForUpdate() { * However, for plain mappings (strings to strings) the result will be null. * */ - @Test + @ProcessorTest public void shouldReturnDefaultForNvmsReturnDefaultForUpdateWithReturn() { Dto dto = new Dto(); @@ -164,7 +149,7 @@ public void shouldReturnDefaultForNvmsReturnDefaultForUpdateWithReturn() { * Test create method ICW presence checker * */ - @Test + @ProcessorTest public void shouldReturnNullForCreateWithPresenceChecker() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); @@ -179,7 +164,7 @@ public void shouldReturnNullForCreateWithPresenceChecker() { * Test update method ICW presence checker * */ - @Test + @ProcessorTest public void shouldReturnNullForUpdateWithPresenceChecker() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); @@ -195,7 +180,7 @@ public void shouldReturnNullForUpdateWithPresenceChecker() { * Test update with return method ICW presence checker * */ - @Test + @ProcessorTest public void shouldReturnNullForUpdateWithReturnWithPresenceChecker() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); @@ -211,8 +196,6 @@ public void shouldReturnNullForUpdateWithReturnWithPresenceChecker() { assertThat( domain2.getLongs() ).isEmpty(); } - - /** * These assert check if non-null and default mapping is working as expected. * diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913SetterMapperForCollectionsTest.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913SetterMapperForCollectionsTest.java index 2665883464..a549011446 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913SetterMapperForCollectionsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_913/Issue913SetterMapperForCollectionsTest.java @@ -1,36 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._913; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.HashSet; import java.util.Set; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * All these test cases test the possible combinations in the SetterMapperForCollections. * @@ -38,7 +23,6 @@ * * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Domain.class, Dto.class, @@ -51,8 +35,8 @@ @IssueKey( "913" ) public class Issue913SetterMapperForCollectionsTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( DomainDtoWithNvmsNullMapper.class, DomainDtoWithNvmsDefaultMapper.class, DomainDtoWithPresenceCheckMapper.class, @@ -68,7 +52,7 @@ public class Issue913SetterMapperForCollectionsTest { * variable for setting {@code strings} as a direct assignment and the copy constructor is used, in case the * assignment is {@code null} then {@code null} should be set for {@code string} */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForCreate() { Dto dto = new Dto(); @@ -84,13 +68,13 @@ public void shouldReturnNullForNvmsReturnNullForCreate() { * conversion from string to long that return null in the entire mapper, so also for the forged * mapper. Note the default NVMS is RETURN_NULL. */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForUpdate() { Dto dto = new Dto(); Domain domain = new Domain(); - domain.setLongs( new HashSet() ); - domain.setStrings( new HashSet() ); + domain.setLongs( new HashSet<>() ); + domain.setStrings( new HashSet<>() ); DomainDtoWithNvmsNullMapper.INSTANCE.update( dto, domain ); doControlAsserts( domain ); @@ -107,14 +91,14 @@ public void shouldReturnNullForNvmsReturnNullForUpdate() { * target (stringsInitialized is Not Null) and source (stringInitialized is Null) target should * be explicitely set to null */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForUpdateWithNonNullTargetAndNullSource() { Dto dto = new Dto(); dto.setStringsInitialized( null ); Domain domain = new Domain(); - domain.setLongs( new HashSet() ); - domain.setStrings( new HashSet() ); + domain.setLongs( new HashSet<>() ); + domain.setStrings( new HashSet<>() ); DomainDtoWithNvmsNullMapper.INSTANCE.update( dto, domain ); assertThat( domain.getStringsInitialized() ).isNull(); @@ -130,13 +114,13 @@ public void shouldReturnNullForNvmsReturnNullForUpdateWithNonNullTargetAndNullSo * conversion from string to long that return null in the entire mapper, so also for the forged * mapper. Note the default NVMS is RETURN_NULL. */ - @Test + @ProcessorTest public void shouldReturnNullForNvmsReturnNullForUpdateWithReturn() { Dto dto = new Dto(); Domain domain1 = new Domain(); - domain1.setLongs( new HashSet() ); - domain1.setStrings( new HashSet() ); + domain1.setLongs( new HashSet<>() ); + domain1.setStrings( new HashSet<>() ); Domain domain2 = DomainDtoWithNvmsNullMapper.INSTANCE.updateWithReturn( dto, domain1 ); doControlAsserts( domain1, domain2 ); @@ -153,7 +137,7 @@ public void shouldReturnNullForNvmsReturnNullForUpdateWithReturn() { * * However, for plain mappings (strings to strings) the result will also be an empty collection. */ - @Test + @ProcessorTest public void shouldReturnDefaultForNvmsReturnDefaultForCreate() { Dto dto = new Dto(); @@ -171,15 +155,15 @@ public void shouldReturnDefaultForNvmsReturnDefaultForCreate() { * * However, for plain mappings (strings to strings) the result will also be an empty collection. */ - @Test + @ProcessorTest public void shouldReturnDefaultForNvmsReturnDefaultForUpdate() { Dto dto = new Dto(); Domain domain = new Domain(); - Set longIn = new HashSet(); + Set longIn = new HashSet<>(); longIn.add( 10L ); domain.setLongs( longIn ); - domain.setStrings( new HashSet() ); + domain.setStrings( new HashSet<>() ); DomainDtoWithNvmsDefaultMapper.INSTANCE.update( dto, domain ); doControlAsserts( domain ); @@ -197,15 +181,15 @@ public void shouldReturnDefaultForNvmsReturnDefaultForUpdate() { * However, for plain mappings (strings to strings) the result will also be an empty collection. * */ - @Test + @ProcessorTest public void shouldReturnDefaultForNvmsReturnDefaultForUpdateWithReturn() { Dto dto = new Dto(); Domain domain1 = new Domain(); - Set longIn = new HashSet(); + Set longIn = new HashSet<>(); longIn.add( 10L ); domain1.setLongs( longIn ); - domain1.setStrings( new HashSet() ); + domain1.setStrings( new HashSet<>() ); domain1.getStrings().add( "30" ); Domain domain2 = DomainDtoWithNvmsDefaultMapper.INSTANCE.updateWithReturn( dto, domain1 ); @@ -224,7 +208,7 @@ public void shouldReturnDefaultForNvmsReturnDefaultForUpdateWithReturn() { * Test create method ICW presence checker. The presence checker is responsible for the null check. * */ - @Test + @ProcessorTest public void shouldReturnNullForCreateWithPresenceChecker() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); @@ -242,14 +226,14 @@ public void shouldReturnNullForCreateWithPresenceChecker() { * */ @IssueKey( "#954") - @Test + @ProcessorTest public void shouldReturnNullForUpdateWithPresenceChecker() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); Domain domain = new Domain(); - domain.setLongs( new HashSet() ); + domain.setLongs( new HashSet<>() ); domain.getLongs().add( 10L ); - domain.setStrings( new HashSet() ); + domain.setStrings( new HashSet<>() ); domain.getStrings().add( "30" ); DomainDtoWithPresenceCheckMapper.INSTANCE.update( dto, domain ); @@ -265,14 +249,14 @@ public void shouldReturnNullForUpdateWithPresenceChecker() { * */ @IssueKey( "#954") - @Test + @ProcessorTest public void shouldReturnNullForUpdateWithReturnWithPresenceChecker() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); Domain domain1 = new Domain(); - domain1.setLongs( new HashSet() ); + domain1.setLongs( new HashSet<>() ); domain1.getLongs().add( 10L ); - domain1.setStrings( new HashSet() ); + domain1.setStrings( new HashSet<>() ); domain1.getStrings().add( "30" ); Domain domain2 = DomainDtoWithPresenceCheckMapper.INSTANCE.updateWithReturn( dto, domain1 ); @@ -290,7 +274,7 @@ public void shouldReturnNullForUpdateWithReturnWithPresenceChecker() { * */ @IssueKey( "#954") - @Test + @ProcessorTest public void shouldReturnNullForCreateWithNcvsAlways() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); @@ -308,14 +292,14 @@ public void shouldReturnNullForCreateWithNcvsAlways() { * */ @IssueKey( "#954") - @Test + @ProcessorTest public void shouldReturnNullForUpdateWithNcvsAlways() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); Domain domain = new Domain(); - domain.setLongs( new HashSet() ); + domain.setLongs( new HashSet<>() ); domain.getLongs().add( 10L ); - domain.setStrings( new HashSet() ); + domain.setStrings( new HashSet<>() ); domain.getStrings().add( "30" ); DomainDtoWithNcvsAlwaysMapper.INSTANCE.update( dto, domain ); @@ -331,14 +315,14 @@ public void shouldReturnNullForUpdateWithNcvsAlways() { * */ @IssueKey( "#954") - @Test + @ProcessorTest public void shouldReturnNullForUpdateWithReturnWithNcvsAlways() { DtoWithPresenceCheck dto = new DtoWithPresenceCheck(); Domain domain1 = new Domain(); - domain1.setLongs( new HashSet() ); + domain1.setLongs( new HashSet<>() ); domain1.getLongs().add( 10L ); - domain1.setStrings( new HashSet() ); + domain1.setStrings( new HashSet<>() ); domain1.getStrings().add( "30" ); Domain domain2 = DomainDtoWithNcvsAlwaysMapper.INSTANCE.updateWithReturn( dto, domain1 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Issue931Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Issue931Test.java index 1c333021d6..25c2baf89d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Issue931Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Issue931Test.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._931; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Verifies that source.nested == null, leads to target.id == null @@ -32,10 +17,9 @@ * @author Sjaak Derksen */ @IssueKey( "931" ) -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses( { Source.class, Nested.class, Target.class, SourceTargetMapper.class } ) public class Issue931Test { - @Test + @ProcessorTest public void shouldMapNestedNullToNull() { Source source = new Source(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Nested.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Nested.java index e66ecfcf60..a31265cd14 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Nested.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Nested.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._931; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Source.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Source.java index 92a48be775..e3faec32aa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._931; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/SourceTargetMapper.java index 755edd1ba5..c418b778e3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._931; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Target.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Target.java index f23dcfca8a..6f1f4b8661 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_931/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._931; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CarMapper.java index afd7784b36..6855f47957 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._955; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CustomMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CustomMapper.java index eeaccfa343..a2a456ca59 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CustomMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/CustomMapper.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._955; import java.util.Map; + import org.mapstruct.MappingTarget; import org.mapstruct.ap.test.bugs._955.dto.Person; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/Issue955Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/Issue955Test.java index e049c250b8..4e03de5373 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/Issue955Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/Issue955Test.java @@ -1,41 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._955; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.bugs._955.dto.Car; import org.mapstruct.ap.test.bugs._955.dto.Person; import org.mapstruct.ap.test.bugs._955.dto.SuperCar; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * * @author Sjaak Derksen */ @IssueKey( "955" ) -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses( { CarMapper.class, CustomMapper.class, Car.class, SuperCar.class, Person.class } ) public class Issue955Test { - @Test + @ProcessorTest public void shouldCompile() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Car.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Car.java index 4226f4e397..5aa4f1e2b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._955.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Person.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Person.java index 673d36c448..82adc0cd97 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._955.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/SuperCar.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/SuperCar.java index f7920850bb..43cbfc3651 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/SuperCar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_955/dto/SuperCar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._955.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionSource.java index 6041810e9f..23873fabf9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionTarget.java index a6b225315b..26652b15fd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/CollectionTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971CollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971CollectionMapper.java index b8f6e70661..d34d6e3dac 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971CollectionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971CollectionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971MapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971MapMapper.java index f53ed7ccde..d96e5f008e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971MapMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971MapMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971Test.java index 7bd6afe0b8..fe178f815b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971Test.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/Issue971Test.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov * */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("971") public class Issue971Test { - @Test + @ProcessorTest @WithClasses({ CollectionSource.class, CollectionTarget.class, Issue971CollectionMapper.class }) public void shouldCompileForCollections() { } - @Test + @ProcessorTest @WithClasses({ MapSource.class, MapTarget.class, Issue971MapMapper.class }) public void shouldCompileForMaps() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapSource.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapSource.java index 5eeaca1685..c56973f23c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapTarget.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapTarget.java index b59ff7f988..43f8abf689 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_971/MapTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.bugs._971; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractBuilderTest.java index a71461fe6b..47a534d20a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractBuilderTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractBuilderTest.java @@ -1,27 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractBuilder; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -36,7 +21,6 @@ ProductDto.class, ProductMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class AbstractBuilderTest { /** @@ -48,7 +32,7 @@ public class AbstractBuilderTest { * - all values are mapped * - all values are set properly */ - @Test + @ProcessorTest public void testThatAbstractBuilderMapsAllProperties() { ImmutableProduct product = ProductMapper.INSTANCE.fromMutable( new ProductDto( "router", 31 ) ); @@ -56,7 +40,7 @@ public void testThatAbstractBuilderMapsAllProperties() { assertThat( product.getName() ).isEqualTo( "router" ); } - @Test + @ProcessorTest public void testThatAbstractBuilderReverseMapsAllProperties() { ProductDto product = ProductMapper.INSTANCE.fromImmutable( ImmutableProduct.builder() .price( 31000 ) diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractImmutableProduct.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractImmutableProduct.java index f1b7291427..f8b9421ebc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractImmutableProduct.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractImmutableProduct.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractBuilder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractProductBuilder.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractProductBuilder.java index 8d47ba3cf5..41ed9d43e5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractProductBuilder.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/AbstractProductBuilder.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractBuilder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ImmutableProduct.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ImmutableProduct.java index 77aeed710a..d3b710cddc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ImmutableProduct.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ImmutableProduct.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractBuilder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductDto.java index 30b4c9d8a9..0e3eaaae6b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractBuilder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductMapper.java index 937935a377..877c18746d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractBuilder/ProductMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractBuilder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/AbstractGenericTargetBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/AbstractGenericTargetBuilderTest.java index cf3913c179..2b77353175 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/AbstractGenericTargetBuilderTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/AbstractGenericTargetBuilderTest.java @@ -1,27 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -39,10 +24,9 @@ ParentSource.class, ParentMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class AbstractGenericTargetBuilderTest { - @Test + @ProcessorTest public void testAbstractTargetMapper() { ParentSource parent = new ParentSource(); parent.setCount( 4 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Child.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Child.java index 306d4b1b61..a136448b18 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Child.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Child.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ChildSource.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ChildSource.java index 1884f8cef4..6a23998adf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ChildSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ChildSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableChild.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableChild.java index becdb4fab1..23dc617408 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableChild.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableChild.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableParent.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableParent.java index 392ccbf979..f0877844a2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableParent.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ImmutableParent.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableChild.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableChild.java index 3232ce89d1..e43417d753 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableChild.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableChild.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableParent.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableParent.java index c8ba05e371..8ad97dbb62 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableParent.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/MutableParent.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Parent.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Parent.java index 5bc5c8d448..8d3f548973 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Parent.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/Parent.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentMapper.java index 372f34dc01..0fa5f5633f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentSource.java b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentSource.java index bf0f378bbb..56e6da533f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/abstractGenericTarget/ParentSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.abstractGenericTarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java index e7ac6c2e99..2846e17795 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.factory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java index 827d3f9f87..5ec38b2d0a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderFactoryMapperTest.java @@ -1,34 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.factory; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ BuilderFactoryMapper.class, BuilderImplicitFactoryMapper.class, @@ -37,7 +21,7 @@ }) public class BuilderFactoryMapperTest { - @Test + @ProcessorTest public void shouldUseBuilderFactory() { Person person = BuilderFactoryMapper.INSTANCE.map( new PersonDto( "Filip" ) ); @@ -45,7 +29,7 @@ public void shouldUseBuilderFactory() { assertThat( person.getSource() ).isEqualTo( "Factory with @ObjectFactory" ); } - @Test + @ProcessorTest public void shouldUseImplicitBuilderFactory() { Person person = BuilderImplicitFactoryMapper.INSTANCE.map( new PersonDto( "Filip" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java index cc1feeafab..916b3cac32 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/BuilderImplicitFactoryMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.factory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java index f94a167546..f371c1566c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.factory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java index 797b7bf56a..ac326e524a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/factory/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.factory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseDto.java index 50b6d35e59..3ababeec92 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseEntity.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseEntity.java index 24ee73188a..7835305be5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BaseEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMapper.java index e3c8dbd81d..9d26b94327 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; @@ -33,6 +20,7 @@ public interface BuilderIgnoringMapper { BuilderIgnoringMapper INSTANCE = Mappers.getMapper( BuilderIgnoringMapper.class ); @InheritConfiguration(name = "mapBase") + @Mapping( target = "lastName" ) Person mapWithIgnoringBase(PersonDto source); @BeanMapping(ignoreByDefault = true) diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMappingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMappingConfig.java index 67a699e536..1cd9be99b1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMappingConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringMappingConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringTest.java index 0538aeda21..5be9d50ff6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/BuilderIgnoringTest.java @@ -1,35 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1452") @WithClasses({ BaseDto.class, @@ -41,7 +25,8 @@ }) public class BuilderIgnoringTest { - @Test + @ProcessorTest + @IssueKey( "1933" ) public void shouldIgnoreBase() { PersonDto source = new PersonDto(); source.setId( 100L ); @@ -51,11 +36,11 @@ public void shouldIgnoreBase() { Person target = BuilderIgnoringMapper.INSTANCE.mapWithIgnoringBase( source ); assertThat( target.getId() ).isNull(); - assertThat( target.getName() ).isEqualTo( "John" ); + assertThat( target.getName() ).isNull(); assertThat( target.getLastName() ).isEqualTo( "Doe" ); } - @Test + @ProcessorTest public void shouldMapOnlyExplicit() { PersonDto source = new PersonDto(); source.setId( 100L ); @@ -69,7 +54,7 @@ public void shouldMapOnlyExplicit() { assertThat( target.getLastName() ).isNull(); } - @Test + @ProcessorTest public void shouldMapAll() { PersonDto source = new PersonDto(); source.setId( 100L ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/Person.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/Person.java index 0fafbae7c7..7ab599bdf4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/PersonDto.java index b3b137f9f9..31d3ac08f1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/ignore/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/BuilderLifecycleCallbacksTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/BuilderLifecycleCallbacksTest.java index 890c96da29..3d5fb7e533 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/BuilderLifecycleCallbacksTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/BuilderLifecycleCallbacksTest.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith( AnnotationProcessorTestRunner.class ) @IssueKey( "1433" ) @WithClasses( { Item.class, @@ -43,7 +27,7 @@ } ) public class BuilderLifecycleCallbacksTest { - @Test + @ProcessorTest public void lifecycleMethodsShouldBeInvoked() { OrderDto source = new OrderDto(); source.setCreator( "Filip" ); @@ -59,12 +43,16 @@ public void lifecycleMethodsShouldBeInvoked() { assertThat( context.getInvokedMethods() ) .contains( "beforeWithoutParameters", + "beforeWithTargetType", "beforeWithBuilderTargetType", "beforeWithBuilderTarget", "afterWithoutParameters", "afterWithBuilderTargetType", "afterWithBuilderTarget", - "afterWithBuilderTargetReturningTarget" + "afterWithBuilderTargetReturningTarget", + "afterWithTargetType", + "afterWithTarget", + "afterWithTargetReturningTarget" ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Item.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Item.java index 636a71b0ec..19da018e85 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Item.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Item.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/ItemDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/ItemDto.java index a14d93265a..664d99c966 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/ItemDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/ItemDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/MappingContext.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/MappingContext.java index 157b5bbce8..2065bad478 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/MappingContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/MappingContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; @@ -31,7 +18,7 @@ */ public class MappingContext { - private final List invokedMethods = new ArrayList(); + private final List invokedMethods = new ArrayList<>(); @BeforeMapping public void beforeWithoutParameters() { @@ -87,7 +74,15 @@ public void afterWithBuilderTarget(OrderDto source, @MappingTarget Order.Builder public Order afterWithBuilderTargetReturningTarget(@MappingTarget Order.Builder orderBuilder) { invokedMethods.add( "afterWithBuilderTargetReturningTarget" ); - return orderBuilder.create(); + // return null, so that @AfterMapping methods on the finalized object will be called in the tests + return null; + } + + @AfterMapping + public Order afterWithTargetReturningTarget(@MappingTarget Order order) { + invokedMethods.add( "afterWithTargetReturningTarget" ); + + return order; } public List getInvokedMethods() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Order.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Order.java index b3d1d3621d..54316bf774 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Order.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/Order.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; @@ -30,7 +17,7 @@ public class Order { private final String creator; public Order(Builder builder) { - this.items = new ArrayList( builder.items ); + this.items = new ArrayList<>( builder.items ); this.creator = builder.creator; } @@ -47,7 +34,7 @@ public static Builder builder() { } public static class Builder { - private List items = new ArrayList(); + private List items = new ArrayList<>(); private String creator; public Builder items(List items) { diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderDto.java index 958a668c07..5da6578a74 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderMapper.java index ccfcb42908..12dab91ce2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/lifecycle/OrderMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.lifecycle; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/BuilderInfoTargetTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/BuilderInfoTargetTest.java index 3a0d6fa5dc..5d0ff919ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/BuilderInfoTargetTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/BuilderInfoTargetTest.java @@ -1,28 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.mappingTarget.simple; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; @@ -33,13 +22,12 @@ SimpleImmutableTarget.class, SimpleBuilderMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class BuilderInfoTargetTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest public void testSimpleImmutableBuilderHappyPath() { SimpleMutableSource source = new SimpleMutableSource(); source.setAge( 3 ); @@ -52,7 +40,19 @@ public void testSimpleImmutableBuilderHappyPath() { assertThat( targetObject.getName() ).isEqualTo( "Bob" ); } - @Test + @ProcessorTest + @IssueKey("1752") + public void testSimpleImmutableBuilderFromNullSource() { + SimpleImmutableTarget targetObject = SimpleBuilderMapper.INSTANCE.toImmutable( + null, + SimpleImmutableTarget.builder().age( 3 ).name( "Bob" ) + ); + assertThat( targetObject ).isNotNull(); + assertThat( targetObject.getAge() ).isEqualTo( 3 ); + assertThat( targetObject.getName() ).isEqualTo( "Bob" ); + } + + @ProcessorTest public void testMutableTargetWithBuilder() { SimpleMutableSource source = new SimpleMutableSource(); source.setAge( 20 ); @@ -63,7 +63,7 @@ public void testMutableTargetWithBuilder() { assertThat( target.getSource() ).isEqualTo( "Builder" ); } - @Test + @ProcessorTest public void testUpdateMutableWithBuilder() { SimpleMutableSource source = new SimpleMutableSource(); source.setAge( 20 ); @@ -82,7 +82,18 @@ public void testUpdateMutableWithBuilder() { assertThat( target.getSource() ).isEqualTo( "Empty constructor" ); } - @Test + @ProcessorTest + @WithClasses( { + SimpleImmutableUpdateMapper.class + } ) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = SimpleImmutableUpdateMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 18, + message = "No target property found for target \"SimpleImmutableTarget\"."), + }) + public void updatingTargetWithNoSettersShouldNotFail() { SimpleMutableSource source = new SimpleMutableSource(); @@ -93,7 +104,7 @@ public void updatingTargetWithNoSettersShouldNotFail() { .build(); assertThat( target.getAge() ).isEqualTo( 20 ); - SimpleBuilderMapper.INSTANCE.toImmutable( source, target ); + SimpleImmutableUpdateMapper.INSTANCE.toImmutable( source, target ); assertThat( target.getAge() ).isEqualTo( 20 ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/MutableTarget.java b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/MutableTarget.java index 374d12f429..02668f5fff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/MutableTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/MutableTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.mappingTarget.simple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleBuilderMapper.java index b79d626ff3..6185daee97 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleBuilderMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleBuilderMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.mappingTarget.simple; @@ -34,9 +21,6 @@ public interface SimpleBuilderMapper { @Mapping(target = "builder.name", source = "source.fullName") void updateImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget.Builder builder); - // This method is fine as if the mapping target has setters it would use them, otherwise it won't - void toImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget target); - @Mapping(target = "name", source = "fullName") SimpleImmutableTarget toImmutable(SimpleMutableSource source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableTarget.java b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableTarget.java index 50b62be8f7..cc7b103dc0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.mappingTarget.simple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableUpdateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableUpdateMapper.java new file mode 100644 index 0000000000..c6eccc96c8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleImmutableUpdateMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.mappingTarget.simple; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SimpleImmutableUpdateMapper { + + SimpleImmutableUpdateMapper INSTANCE = Mappers.getMapper( SimpleImmutableUpdateMapper.class ); + + // This method is fine as if the mapping target has setters it would use them, otherwise it won't + void toImmutable(SimpleMutableSource source, @MappingTarget SimpleImmutableTarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleMutableSource.java b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleMutableSource.java index 4b23a79938..9befd215a0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleMutableSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/mappingTarget/simple/SimpleMutableSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.mappingTarget.simple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderConfigDefinedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderConfigDefinedMapper.java index 79eb4de38e..3a2d6a2c60 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderConfigDefinedMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderConfigDefinedMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderDefinedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderDefinedMapper.java index 85e497ce25..2cccbc0afb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderDefinedMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderDefinedMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderMapperConfig.java index 90f69a1497..2bd52af4b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderMapperConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/BuilderMapperConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/DefaultBuildMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/DefaultBuildMethodMapper.java index ce39c7e367..8e66255d59 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/DefaultBuildMethodMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/DefaultBuildMethodMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodMapper.java index dedad6f2d4..1c591f8e48 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodWithMapperDefinedMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodWithMapperDefinedMappingMapper.java index a7ff63573d..34194e5025 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodWithMapperDefinedMappingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/ErroneousMoreThanOneBuildMethodWithMapperDefinedMappingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/MultipleBuilderMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/MultipleBuilderMapperTest.java index 12bd0dd635..825794d6d7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/MultipleBuilderMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/MultipleBuilderMapperTest.java @@ -1,40 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.builder.multiple.build.Process; import org.mapstruct.ap.test.builder.multiple.builder.Case; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1479") @WithClasses({ Process.class, @@ -52,27 +36,21 @@ public class MultipleBuilderMapperTest { @Diagnostic( type = ErroneousMoreThanOneBuildMethodMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = "No build method \"build\" found in \".*\\.multiple\\.build\\.Process\\.Builder\" " + - "for \".*\\.multiple\\.build\\.Process\"\\. " + - "Found methods: " + - "\".*wrongCreate\\(\\) ?, " + - ".*create\\(\\) ?\"\\. " + - "Consider to add @Builder in order to select the correct build method." + line = 19, + message = "No build method \"build\" found in \"org.mapstruct.ap.test.builder.multiple.build.Process" + + ".Builder\" for \"org.mapstruct.ap.test.builder.multiple.build.Process\". Found methods: " + + "\"wrongCreate(), create()\". Consider to add @Builder in order to select the correct build method." ), @Diagnostic( type = ErroneousMoreThanOneBuildMethodMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 34, - messageRegExp = "No build method \"missingBuild\" found " + - "in \".*\\.multiple\\.build\\.Process\\.Builder\" " + - "for \".*\\.multiple\\.build\\.Process\"\\. " + - "Found methods: " + - "\".*wrongCreate\\(\\) ?, " + - ".*create\\(\\) ?\"\\." + line = 21, + message = "No build method \"missingBuild\" found in \"org.mapstruct.ap.test.builder.multiple.build" + + ".Process.Builder\" for \"org.mapstruct.ap.test.builder.multiple.build.Process\". Found methods: " + + "\"wrongCreate(), create()\"." ) }) - @Test + @ProcessorTest public void moreThanOneBuildMethod() { } @@ -84,23 +62,21 @@ public void moreThanOneBuildMethod() { @Diagnostic( type = ErroneousMoreThanOneBuildMethodWithMapperDefinedMappingMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 31, - messageRegExp = - "No build method \"mapperBuild\" found in \".*\\.multiple\\.build\\.Process\\.Builder\" " + - "for \".*\\.multiple\\.build\\.Process\"\\. " + - "Found methods: " + - "\".*wrongCreate\\(\\) ?, " + - ".*create\\(\\) ?\"\\." + line = 18, + message = + "No build method \"mapperBuild\" found in \"org.mapstruct.ap.test.builder.multiple.build.Process" + + ".Builder\" for \"org.mapstruct.ap.test.builder.multiple.build.Process\". Found methods: " + + "\"wrongCreate(), create()\"." ) }) - @Test + @ProcessorTest public void moreThanOneBuildMethodDefinedOnMapper() { } @WithClasses({ BuilderDefinedMapper.class }) - @Test + @ProcessorTest public void builderMappingDefined() { Process map = BuilderDefinedMapper.INSTANCE.map( new Source( "map" ) ); Process wrongMap = BuilderDefinedMapper.INSTANCE.wrongMap( new Source( "wrongMap" ) ); @@ -113,7 +89,7 @@ public void builderMappingDefined() { BuilderMapperConfig.class, BuilderConfigDefinedMapper.class }) - @Test + @ProcessorTest public void builderMappingMapperConfigDefined() { Process map = BuilderConfigDefinedMapper.INSTANCE.map( new Source( "map" ) ); Process wrongMap = BuilderConfigDefinedMapper.INSTANCE.wrongMap( new Source( "wrongMap" ) ); @@ -126,30 +102,17 @@ public void builderMappingMapperConfigDefined() { TooManyBuilderCreationMethodsMapper.class }) @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, - // We have 2 diagnostics, as we don't do caching of the types, so a type is processed multiple types diagnostics = { @Diagnostic( type = Case.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 24, - messageRegExp = "More than one builder creation method for \".*\\.multiple\\.builder.Case\"\\. " + - "Found methods: " + - "\".*wrongBuilder\\(\\) ?, " + - ".*builder\\(\\) ?\"\\. " + - "Builder will not be used\\. Consider implementing a custom BuilderProvider SPI\\." - ), - @Diagnostic( - type = Case.class, - kind = javax.tools.Diagnostic.Kind.WARNING, - line = 24, - messageRegExp = "More than one builder creation method for \".*\\.multiple\\.builder.Case\"\\. " + - "Found methods: " + - "\".*wrongBuilder\\(\\) ?, " + - ".*builder\\(\\) ?\"\\. " + - "Builder will not be used\\. Consider implementing a custom BuilderProvider SPI\\." + line = 11, + message = "More than one builder creation method for \"org.mapstruct.ap.test.builder.multiple.builder" + + ".Case\". Found methods: \"wrongBuilder(), builder()\". Builder will not be used. Consider " + + "implementing a custom BuilderProvider SPI." ) }) - @Test + @ProcessorTest public void tooManyBuilderCreationMethods() { Case caseTarget = TooManyBuilderCreationMethodsMapper.INSTANCE.map( new Source( "test" ) ); @@ -162,7 +125,7 @@ public void tooManyBuilderCreationMethods() { @WithClasses( { DefaultBuildMethodMapper.class } ) - @Test + @ProcessorTest public void defaultBuildMethod() { Task task = DefaultBuildMethodMapper.INSTANCE.map( new Source( "test" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Source.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Source.java index 93c0ab59f4..04701b8472 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Task.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Task.java index 234fe6e851..67317d2edd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Task.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/Task.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/TooManyBuilderCreationMethodsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/TooManyBuilderCreationMethodsMapper.java index 1b935eb2ef..a5d7b6d38c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/TooManyBuilderCreationMethodsMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/TooManyBuilderCreationMethodsMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/build/Process.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/build/Process.java index 939249f531..8e30310c6f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/build/Process.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/build/Process.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple.build; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/builder/Case.java b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/builder/Case.java index a4251abd5f..d1d9805462 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/builder/Case.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/multiple/builder/Case.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.multiple.builder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/BuilderNestedPropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/BuilderNestedPropertyTest.java index cad6440276..94233a373e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/BuilderNestedPropertyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/BuilderNestedPropertyTest.java @@ -1,27 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.expanding; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -34,10 +19,9 @@ ImmutableArticle.class, ExpandingMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class BuilderNestedPropertyTest { - @Test + @ProcessorTest public void testNestedImmutablePropertyMapper() { FlattenedStock stock = new FlattenedStock( "Sock", "Tie", 33 ); ImmutableExpandedStock expandedTarget = ExpandingMapper.INSTANCE.writeToNestedProperty( stock ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ExpandingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ExpandingMapper.java index b9d855bcfb..9b2196da07 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ExpandingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ExpandingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.expanding; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/FlattenedStock.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/FlattenedStock.java index 682ab86e32..f7cce1a03f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/FlattenedStock.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/FlattenedStock.java @@ -1,24 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.expanding; -import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Objects.requireNonNull; public class FlattenedStock { private String article1; @@ -29,8 +16,8 @@ public FlattenedStock() { } public FlattenedStock(String article1, String article2, int count) { - this.article1 = checkNotNull( article1 ); - this.article2 = checkNotNull( article2 ); + this.article1 = requireNonNull( article1 ); + this.article2 = requireNonNull( article2 ); this.count = count; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableArticle.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableArticle.java index 622fbeaba0..2d86e74d0d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableArticle.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableArticle.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.expanding; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableExpandedStock.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableExpandedStock.java index 067218b4d1..2bfc65f0b0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableExpandedStock.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/expanding/ImmutableExpandedStock.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.expanding; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Article.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Article.java index 5f5020519c..c24cb55b5f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Article.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Article.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.flattening; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/BuilderNestedPropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/BuilderNestedPropertyTest.java index fbf1b32332..861bf810bf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/BuilderNestedPropertyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/BuilderNestedPropertyTest.java @@ -1,27 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.flattening; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -34,10 +19,9 @@ Article.class, FlatteningMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class BuilderNestedPropertyTest { - @Test + @ProcessorTest public void testNestedImmutablePropertyMapper() { Stock stock = new Stock(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/FlatteningMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/FlatteningMapper.java index 75a339b53e..b3b4123e83 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/FlatteningMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/FlatteningMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.flattening; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/ImmutableFlattenedStock.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/ImmutableFlattenedStock.java index 461bd3e7dc..bc941fc290 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/ImmutableFlattenedStock.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/ImmutableFlattenedStock.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.flattening; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Stock.java b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Stock.java index ab10144e1f..56845d1163 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Stock.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/nestedprop/flattening/Stock.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.nestedprop.flattening; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/NoOpBuilderProviderTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/NoOpBuilderProviderTest.java index fa72dc47c5..e90babfdd8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/NoOpBuilderProviderTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/NoOpBuilderProviderTest.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.noop; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.spi.NoOpBuilderProvider; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithServiceImplementation; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith( AnnotationProcessorTestRunner.class ) @IssueKey( "1418" ) @WithServiceImplementation(NoOpBuilderProvider.class) @WithClasses( { @@ -41,7 +25,7 @@ } ) public class NoOpBuilderProviderTest { - @Test + @ProcessorTest public void shouldNotUseBuilder() { Person person = PersonMapper.INSTANCE.map( new PersonDto( "Filip" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/Person.java b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/Person.java index f40e49f8a4..02e371f773 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.noop; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonDto.java index b36f62acb0..f739803330 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.noop; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonMapper.java index d2146690d9..1aa0072dc3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/noop/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.noop; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleMapper.java new file mode 100644 index 0000000000..94e5101720 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.off; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Builder; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface SimpleMapper { + + @BeanMapping( builder = @Builder( disableBuilder = true ) ) + @Mapping(target = "name", source = "fullName") + SimpleNotRealyImmutablePerson toNotRealyImmutable(SimpleMutablePerson source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleMutablePerson.java b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleMutablePerson.java new file mode 100644 index 0000000000..d3cde44d21 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleMutablePerson.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.off; + +public class SimpleMutablePerson { + private String fullName; + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleNotRealyImmutableBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleNotRealyImmutableBuilderTest.java new file mode 100644 index 0000000000..30cf5ff12d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleNotRealyImmutableBuilderTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.off; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1661") +@WithClasses({ + SimpleMutablePerson.class, + SimpleNotRealyImmutablePerson.class +}) +public class SimpleNotRealyImmutableBuilderTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ SimpleMapper.class }) + public void testSimpleImmutableBuilderHappyPath() { + SimpleMapper mapper = Mappers.getMapper( SimpleMapper.class ); + SimpleMutablePerson source = new SimpleMutablePerson(); + source.setFullName( "Bob" ); + + SimpleNotRealyImmutablePerson targetObject = mapper.toNotRealyImmutable( source ); + + assertThat( targetObject.getName() ).isEqualTo( "Bob" ); + + } + + @ProcessorTest + @WithClasses({ SimpleWithBuilderMapper.class }) + @ProcessorOption( name = "mapstruct.disableBuilders", value = "true") + public void builderGloballyDisabled() { + SimpleWithBuilderMapper mapper = Mappers.getMapper( SimpleWithBuilderMapper.class ); + SimpleMutablePerson source = new SimpleMutablePerson(); + source.setFullName( "Bob" ); + + SimpleNotRealyImmutablePerson targetObject = mapper.toNotRealyImmutable( source ); + + assertThat( targetObject.getName() ).isEqualTo( "Bob" ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleNotRealyImmutablePerson.java b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleNotRealyImmutablePerson.java new file mode 100644 index 0000000000..4caba6b016 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleNotRealyImmutablePerson.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.off; + +public class SimpleNotRealyImmutablePerson { + + private String name; + + public static Builder builder() { + return new Builder(); + } + + public SimpleNotRealyImmutablePerson() { + } + + SimpleNotRealyImmutablePerson(Builder builder) { + this.name = builder.name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public static class Builder { + + private String name; + + public Builder name(String name) { + throw new IllegalStateException( "name should not be called on builder" ); + } + + public SimpleNotRealyImmutablePerson build() { + return new SimpleNotRealyImmutablePerson( this ); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleWithBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleWithBuilderMapper.java new file mode 100644 index 0000000000..6df547db78 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/off/SimpleWithBuilderMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.off; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface SimpleWithBuilderMapper { + + @Mapping(target = "name", source = "fullName") + SimpleNotRealyImmutablePerson toNotRealyImmutable(SimpleMutablePerson source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableChild.java b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableChild.java index 3f95ce98cf..e4d067c704 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableChild.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableChild.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.parentchild; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableParent.java b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableParent.java index 88d9967c02..b77860532b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableParent.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ImmutableParent.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.parentchild; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableChild.java b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableChild.java index a3688275d3..e1e2b7c71f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableChild.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableChild.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.parentchild; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableParent.java b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableParent.java index b0b975b35a..ef91baef48 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableParent.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/MutableParent.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.parentchild; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildBuilderTest.java index 671c095cc8..9269390640 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildBuilderTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildBuilderTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.parentchild; import java.util.ArrayList; import org.assertj.core.api.Condition; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -35,14 +20,13 @@ ImmutableParent.class, ParentChildMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ParentChildBuilderTest { - @Test + @ProcessorTest public void testParentChildBuilderMapper() { final MutableParent parent = new MutableParent(); parent.setCount( 4 ); - parent.setChildren( new ArrayList() ); + parent.setChildren( new ArrayList<>() ); parent.getChildren().add( new MutableChild( "Phineas" ) ); parent.getChildren().add( new MutableChild( "Ferb" ) ); @@ -58,7 +42,7 @@ public void testParentChildBuilderMapper() { } private Condition hasMatchingName(final String name) { - return new Condition( "Matching name" ) { + return new Condition<>( "Matching name" ) { @Override public boolean matches(ImmutableChild value) { return name.equals( value.getName() ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildMapper.java index 479d4f5e92..179c9f947c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/parentchild/ParentChildMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.parentchild; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/ErroneousSimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/ErroneousSimpleBuilderMapper.java deleted file mode 100644 index f5812aaa85..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/ErroneousSimpleBuilderMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.builder.simple; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.ReportingPolicy; - -@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) -public interface ErroneousSimpleBuilderMapper { - - @Mappings({ - @Mapping(target = "address", ignore = true ), - @Mapping(target = "job", ignore = true ), - @Mapping(target = "city", ignore = true ) - }) - SimpleImmutablePerson toImmutable(SimpleMutablePerson source); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleBuilderMapper.java deleted file mode 100644 index 3b430b8246..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleBuilderMapper.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.builder.simple; - -import org.mapstruct.CollectionMappingStrategy; -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; - -@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) -public interface SimpleBuilderMapper { - - @Mappings({ - @Mapping(target = "name", source = "fullName"), - @Mapping(target = "job", constant = "programmer"), - @Mapping(target = "city", expression = "java(\"Bengalore\")") - }) - SimpleImmutablePerson toImmutable(SimpleMutablePerson source); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleImmutableBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleImmutableBuilderTest.java deleted file mode 100644 index 5afa4e6682..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleImmutableBuilderTest.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.builder.simple; - -import java.util.Arrays; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; -import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; -import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -import org.mapstruct.ap.testutil.runner.GeneratedSource; -import org.mapstruct.factory.Mappers; - -import static org.assertj.core.api.Assertions.assertThat; - -@WithClasses({ - SimpleMutablePerson.class, - SimpleImmutablePerson.class -}) -@RunWith(AnnotationProcessorTestRunner.class) -public class SimpleImmutableBuilderTest { - - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); - - @Test - @WithClasses({ SimpleBuilderMapper.class }) - public void testSimpleImmutableBuilderHappyPath() { - SimpleBuilderMapper mapper = Mappers.getMapper( SimpleBuilderMapper.class ); - SimpleMutablePerson source = new SimpleMutablePerson(); - source.setAge( 3 ); - source.setFullName( "Bob" ); - source.setChildren( Arrays.asList( "Alice", "Tom" ) ); - source.setAddress( "Plaza 1" ); - - SimpleImmutablePerson targetObject = mapper.toImmutable( source ); - - assertThat( targetObject.getAge() ).isEqualTo( 3 ); - assertThat( targetObject.getName() ).isEqualTo( "Bob" ); - assertThat( targetObject.getJob() ).isEqualTo( "programmer" ); - assertThat( targetObject.getCity() ).isEqualTo( "Bengalore" ); - assertThat( targetObject.getAddress() ).isEqualTo( "Plaza 1" ); - assertThat( targetObject.getChildren() ).contains( "Alice", "Tom" ); - } - - @Test - @WithClasses({ ErroneousSimpleBuilderMapper.class }) - @ExpectedCompilationOutcome(value = CompilationResult.FAILED, - diagnostics = @Diagnostic( - kind = javax.tools.Diagnostic.Kind.ERROR, - type = ErroneousSimpleBuilderMapper.class, - line = 34, - messageRegExp = "Unmapped target property: \"name\"\\.")) - public void testSimpleImmutableBuilderMissingPropertyFailsToCompile() { - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleImmutablePerson.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleImmutablePerson.java deleted file mode 100644 index 0d9a92b745..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleImmutablePerson.java +++ /dev/null @@ -1,115 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.builder.simple; - -import java.util.ArrayList; -import java.util.List; - -public class SimpleImmutablePerson { - private final String name; - private final int age; - private final String job; - private final String city; - private final String address; - private final List children; - - SimpleImmutablePerson(Builder builder) { - this.name = builder.name; - this.age = builder.age; - this.job = builder.job; - this.city = builder.city; - this.address = builder.address; - this.children = new ArrayList( builder.children ); - } - - public static Builder builder() { - return new Builder(); - } - - public int getAge() { - return age; - } - - public String getName() { - return name; - } - - public String getJob() { - return job; - } - - public String getCity() { - return city; - } - - public String getAddress() { - return address; - } - - public List getChildren() { - return children; - } - - public static class Builder { - private String name; - private int age; - private String job; - private String city; - private String address; - private List children = new ArrayList(); - - public Builder age(int age) { - this.age = age; - return this; - } - - public SimpleImmutablePerson build() { - return new SimpleImmutablePerson( this ); - } - - public Builder name(String name) { - this.name = name; - return this; - } - - public Builder job(String job) { - this.job = job; - return this; - } - - public Builder city(String city) { - this.city = city; - return this; - } - - public Builder address(String address) { - this.address = address; - return this; - } - - public List getChildren() { - throw new UnsupportedOperationException( "This is just a marker method" ); - } - - public Builder addChild(String child) { - this.children.add( child ); - return this; - } - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleMutablePerson.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleMutablePerson.java index 52b6c49ee2..34fd71ad92 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleMutablePerson.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/SimpleMutablePerson.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builder.simple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/ErroneousSimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/ErroneousSimpleBuilderMapper.java new file mode 100644 index 0000000000..18e82ed19c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/ErroneousSimpleBuilderMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.innerclass; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.builder.simple.SimpleMutablePerson; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface ErroneousSimpleBuilderMapper { + + @Mappings({ + @Mapping(target = "address", ignore = true ), + @Mapping(target = "job", ignore = true ), + @Mapping(target = "city", ignore = true ) + }) + SimpleImmutablePersonWithInnerClassBuilder toImmutable(SimpleMutablePerson source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleBuilderMapper.java new file mode 100644 index 0000000000..e2c673401a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleBuilderMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.innerclass; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.builder.simple.SimpleMutablePerson; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface SimpleBuilderMapper { + + @Mappings({ + @Mapping(target = "name", source = "fullName"), + @Mapping(target = "job", constant = "programmer"), + @Mapping(target = "city", expression = "java(\"Bengalore\")") + }) + SimpleImmutablePersonWithInnerClassBuilder toImmutable(SimpleMutablePerson source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleImmutableBuilderThroughInnerClassConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleImmutableBuilderThroughInnerClassConstructorTest.java new file mode 100644 index 0000000000..0a2c5287bc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleImmutableBuilderThroughInnerClassConstructorTest.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.innerclass; + +import java.util.Arrays; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.builder.simple.SimpleMutablePerson; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + SimpleMutablePerson.class, + SimpleImmutablePersonWithInnerClassBuilder.class +}) +public class SimpleImmutableBuilderThroughInnerClassConstructorTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ SimpleBuilderMapper.class }) + public void testSimpleImmutableBuilderThroughInnerClassConstructorHappyPath() { + SimpleBuilderMapper mapper = Mappers.getMapper( SimpleBuilderMapper.class ); + SimpleMutablePerson source = new SimpleMutablePerson(); + source.setAge( 3 ); + source.setFullName( "Bob" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + source.setAddress( "Plaza 1" ); + + SimpleImmutablePersonWithInnerClassBuilder targetObject = mapper.toImmutable( source ); + + assertThat( targetObject.getAge() ).isEqualTo( 3 ); + assertThat( targetObject.getName() ).isEqualTo( "Bob" ); + assertThat( targetObject.getJob() ).isEqualTo( "programmer" ); + assertThat( targetObject.getCity() ).isEqualTo( "Bengalore" ); + assertThat( targetObject.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( targetObject.getChildren() ).contains( "Alice", "Tom" ); + } + + @ProcessorTest + @WithClasses({ ErroneousSimpleBuilderMapper.class }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousSimpleBuilderMapper.class, + line = 22, + message = "Unmapped target property: \"name\".")) + public void testSimpleImmutableBuilderThroughInnerClassConstructorMissingPropertyFailsToCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleImmutablePersonWithInnerClassBuilder.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleImmutablePersonWithInnerClassBuilder.java new file mode 100644 index 0000000000..a9bda42d33 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/innerclass/SimpleImmutablePersonWithInnerClassBuilder.java @@ -0,0 +1,98 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.innerclass; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleImmutablePersonWithInnerClassBuilder { + private final String name; + private final int age; + private final String job; + private final String city; + private final String address; + private final List children; + + SimpleImmutablePersonWithInnerClassBuilder(Builder builder) { + this.name = builder.name; + this.age = builder.age; + this.job = builder.job; + this.city = builder.city; + this.address = builder.address; + this.children = new ArrayList<>(builder.children); + } + + public int getAge() { + return age; + } + + public String getName() { + return name; + } + + public String getJob() { + return job; + } + + public String getCity() { + return city; + } + + public String getAddress() { + return address; + } + + public List getChildren() { + return children; + } + + public static class Builder { + private String name; + private int age; + private String job; + private String city; + private String address; + private List children = new ArrayList<>(); + + public Builder age(int age) { + this.age = age; + return this; + } + + public SimpleImmutablePersonWithInnerClassBuilder build() { + return new SimpleImmutablePersonWithInnerClassBuilder( this ); + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder job(String job) { + this.job = job; + return this; + } + + public Builder city(String city) { + this.city = city; + return this; + } + + public Builder address(String address) { + this.address = address; + return this; + } + + public List getChildren() { + throw new UnsupportedOperationException( "This is just a marker method" ); + } + + public Builder addChild(String child) { + this.children.add( child ); + return this; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/ErroneousSimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/ErroneousSimpleBuilderMapper.java new file mode 100644 index 0000000000..6fc51ace3d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/ErroneousSimpleBuilderMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.staticfactorymethod; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.builder.simple.SimpleMutablePerson; + +@Mapper(unmappedTargetPolicy = ReportingPolicy.ERROR) +public interface ErroneousSimpleBuilderMapper { + + @Mappings({ + @Mapping(target = "address", ignore = true ), + @Mapping(target = "job", ignore = true ), + @Mapping(target = "city", ignore = true ) + }) + SimpleImmutablePersonWithStaticFactoryMethodBuilder toImmutable(SimpleMutablePerson source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleBuilderMapper.java new file mode 100644 index 0000000000..4bd200bc7c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleBuilderMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.staticfactorymethod; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.builder.simple.SimpleMutablePerson; + +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface SimpleBuilderMapper { + + @Mappings({ + @Mapping(target = "name", source = "fullName"), + @Mapping(target = "job", constant = "programmer"), + @Mapping(target = "city", expression = "java(\"Bengalore\")") + }) + SimpleImmutablePersonWithStaticFactoryMethodBuilder toImmutable(SimpleMutablePerson source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleImmutableBuilderThroughStaticFactoryMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleImmutableBuilderThroughStaticFactoryMethodTest.java new file mode 100644 index 0000000000..90fac6061e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleImmutableBuilderThroughStaticFactoryMethodTest.java @@ -0,0 +1,61 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.staticfactorymethod; + +import java.util.Arrays; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.builder.simple.SimpleMutablePerson; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.mapstruct.factory.Mappers; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + SimpleMutablePerson.class, + SimpleImmutablePersonWithStaticFactoryMethodBuilder.class +}) +public class SimpleImmutableBuilderThroughStaticFactoryMethodTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ SimpleBuilderMapper.class }) + public void testSimpleImmutableBuilderThroughStaticFactoryMethodHappyPath() { + SimpleBuilderMapper mapper = Mappers.getMapper( SimpleBuilderMapper.class ); + SimpleMutablePerson source = new SimpleMutablePerson(); + source.setAge( 3 ); + source.setFullName( "Bob" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + source.setAddress( "Plaza 1" ); + + SimpleImmutablePersonWithStaticFactoryMethodBuilder targetObject = mapper.toImmutable( source ); + + assertThat( targetObject.getAge() ).isEqualTo( 3 ); + assertThat( targetObject.getName() ).isEqualTo( "Bob" ); + assertThat( targetObject.getJob() ).isEqualTo( "programmer" ); + assertThat( targetObject.getCity() ).isEqualTo( "Bengalore" ); + assertThat( targetObject.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( targetObject.getChildren() ).contains( "Alice", "Tom" ); + } + + @ProcessorTest + @WithClasses({ ErroneousSimpleBuilderMapper.class }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousSimpleBuilderMapper.class, + line = 22, + message = "Unmapped target property: \"name\".")) + public void testSimpleImmutableBuilderThroughStaticFactoryMethodMissingPropertyFailsToCompile() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleImmutablePersonWithStaticFactoryMethodBuilder.java b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleImmutablePersonWithStaticFactoryMethodBuilder.java new file mode 100644 index 0000000000..c3dc590210 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builder/simple/staticfactorymethod/SimpleImmutablePersonWithStaticFactoryMethodBuilder.java @@ -0,0 +1,105 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builder.simple.staticfactorymethod; + +import java.util.ArrayList; +import java.util.List; + +public class SimpleImmutablePersonWithStaticFactoryMethodBuilder { + private final String name; + private final int age; + private final String job; + private final String city; + private final String address; + private final List children; + + SimpleImmutablePersonWithStaticFactoryMethodBuilder(Builder builder) { + this.name = builder.name; + this.age = builder.age; + this.job = builder.job; + this.city = builder.city; + this.address = builder.address; + this.children = new ArrayList<>( builder.children ); + } + + public static Builder builder() { + return new Builder(); + } + + public int getAge() { + return age; + } + + public String getName() { + return name; + } + + public String getJob() { + return job; + } + + public String getCity() { + return city; + } + + public String getAddress() { + return address; + } + + public List getChildren() { + return children; + } + + public static class Builder { + private String name; + private int age; + private String job; + private String city; + private String address; + private List children = new ArrayList<>(); + + private Builder() { + } + + public Builder age(int age) { + this.age = age; + return this; + } + + public SimpleImmutablePersonWithStaticFactoryMethodBuilder build() { + return new SimpleImmutablePersonWithStaticFactoryMethodBuilder( this ); + } + + public Builder name(String name) { + this.name = name; + return this; + } + + public Builder job(String job) { + this.job = job; + return this; + } + + public Builder city(String city) { + this.city = city; + return this; + } + + public Builder address(String address) { + this.address = address; + return this; + } + + public List getChildren() { + throw new UnsupportedOperationException( "This is just a marker method" ); + } + + public Builder addChild(String child) { + this.children.add( child ); + return this; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java index 62e6267072..c8ee922af9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/BuiltInTest.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin; -import static org.assertj.core.api.Assertions.assertThat; - +import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.ZoneId; @@ -31,26 +17,24 @@ import java.util.GregorianCalendar; import java.util.HashMap; import java.util.List; -import java.util.TimeZone; - import javax.xml.bind.JAXBElement; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.MethodSorters; +import org.junitpioneer.jupiter.DefaultTimeZone; import org.mapstruct.ap.test.builtin._target.IterableTarget; import org.mapstruct.ap.test.builtin._target.MapTarget; +import org.mapstruct.ap.test.builtin.bean.BigDecimalProperty; import org.mapstruct.ap.test.builtin.bean.CalendarProperty; import org.mapstruct.ap.test.builtin.bean.DateProperty; +import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementListProperty; +import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementProperty; import org.mapstruct.ap.test.builtin.bean.JaxbElementListProperty; import org.mapstruct.ap.test.builtin.bean.JaxbElementProperty; +import org.mapstruct.ap.test.builtin.bean.SomeType; +import org.mapstruct.ap.test.builtin.bean.SomeTypeProperty; import org.mapstruct.ap.test.builtin.bean.StringListProperty; import org.mapstruct.ap.test.builtin.bean.StringProperty; import org.mapstruct.ap.test.builtin.bean.XmlGregorianCalendarProperty; @@ -63,6 +47,8 @@ import org.mapstruct.ap.test.builtin.mapper.DateToCalendarMapper; import org.mapstruct.ap.test.builtin.mapper.DateToXmlGregCalMapper; import org.mapstruct.ap.test.builtin.mapper.IterableSourceTargetMapper; +import org.mapstruct.ap.test.builtin.mapper.JakartaJaxbListMapper; +import org.mapstruct.ap.test.builtin.mapper.JakartaJaxbMapper; import org.mapstruct.ap.test.builtin.mapper.JaxbListMapper; import org.mapstruct.ap.test.builtin.mapper.JaxbMapper; import org.mapstruct.ap.test.builtin.mapper.MapSourceTargetMapper; @@ -74,8 +60,12 @@ import org.mapstruct.ap.test.builtin.source.IterableSource; import org.mapstruct.ap.test.builtin.source.MapSource; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJakartaJaxb; +import org.mapstruct.ap.testutil.WithJavaxJaxb; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for the generation of built-in mapping methods. @@ -87,51 +77,25 @@ MapTarget.class, CalendarProperty.class, DateProperty.class, - JaxbElementListProperty.class, - JaxbElementProperty.class, StringListProperty.class, StringProperty.class, + BigDecimalProperty.class, + SomeTypeProperty.class, + SomeType.class, XmlGregorianCalendarProperty.class, ZonedDateTimeProperty.class, - CalendarToZonedDateTimeMapper.class, - ZonedDateTimeToCalendarMapper.class, - CalendarToDateMapper.class, - CalendarToStringMapper.class, - CalendarToXmlGregCalMapper.class, - DateToCalendarMapper.class, - DateToXmlGregCalMapper.class, - IterableSourceTargetMapper.class, - JaxbListMapper.class, - JaxbMapper.class, - MapSourceTargetMapper.class, - StringToCalendarMapper.class, - StringToXmlGregCalMapper.class, - XmlGregCalToCalendarMapper.class, - XmlGregCalToDateMapper.class, - XmlGregCalToStringMapper.class, IterableSource.class, - MapSource.class }) -@RunWith(AnnotationProcessorTestRunner.class) -@FixMethodOrder(MethodSorters.NAME_ASCENDING) +@DefaultTimeZone("Europe/Berlin") public class BuiltInTest { - private static TimeZone originalTimeZone; - - @BeforeClass - public static void setDefaultTimeZoneToCet() { - originalTimeZone = TimeZone.getDefault(); - TimeZone.setDefault( TimeZone.getTimeZone( "Europe/Berlin" ) ); - } - - @AfterClass - public static void restoreOriginalTimeZone() { - TimeZone.setDefault( originalTimeZone ); - } - - @Test - public void shouldApplyBuiltInOnJAXBElement() throws ParseException, DatatypeConfigurationException { - + @ProcessorTest + @WithClasses( { + JaxbMapper.class, + JaxbElementProperty.class, + } ) + @WithJavaxJaxb + public void shouldApplyBuiltInOnJAXBElement() { JaxbElementProperty source = new JaxbElementProperty(); source.setProp( createJaxb( "TEST" ) ); source.publicProp = createJaxb( "PUBLIC TEST" ); @@ -142,9 +106,85 @@ public void shouldApplyBuiltInOnJAXBElement() throws ParseException, DatatypeCon assertThat( target.publicProp ).isEqualTo( "PUBLIC TEST" ); } - @Test + @ProcessorTest + @WithClasses( { + JakartaJaxbMapper.class, + JakartaJaxbElementProperty.class, + } ) + @WithJakartaJaxb + public void shouldApplyBuiltInOnJakartaJaxbElement() { + JakartaJaxbElementProperty source = new JakartaJaxbElementProperty(); + source.setProp( createJakartaJaxb( "TEST" ) ); + source.publicProp = createJakartaJaxb( "PUBLIC TEST" ); + + StringProperty target = JakartaJaxbMapper.INSTANCE.map( source ); + assertThat( target ).isNotNull(); + assertThat( target.getProp() ).isEqualTo( "TEST" ); + assertThat( target.publicProp ).isEqualTo( "PUBLIC TEST" ); + } + + @ProcessorTest + @WithClasses( { + JaxbMapper.class, + JaxbElementProperty.class, + } ) + @WithJavaxJaxb + @IssueKey( "1698" ) + public void shouldApplyBuiltInOnJAXBElementExtra() { + JaxbElementProperty source = new JaxbElementProperty(); + source.setProp( createJaxb( "5" ) ); + source.publicProp = createJaxb( "5" ); + + BigDecimalProperty target = JaxbMapper.INSTANCE.mapBD( source ); + assertThat( target ).isNotNull(); + assertThat( target.getProp() ).isEqualTo( new BigDecimal( "5" ) ); + assertThat( target.publicProp ).isEqualTo( new BigDecimal( "5" ) ); + + JaxbElementProperty source2 = new JaxbElementProperty(); + source2.setProp( createJaxb( "5" ) ); + source2.publicProp = createJaxb( "5" ); + + SomeTypeProperty target2 = JaxbMapper.INSTANCE.mapSomeType( source2 ); + assertThat( target2 ).isNotNull(); + assertThat( target2.publicProp ).isNotNull(); + assertThat( target2.getProp() ).isNotNull(); + } + + @ProcessorTest + @WithClasses( { + JakartaJaxbMapper.class, + JakartaJaxbElementProperty.class, + } ) + @WithJakartaJaxb + @IssueKey( "1698" ) + public void shouldApplyBuiltInOnJakartaJAXBElementExtra() { + JakartaJaxbElementProperty source = new JakartaJaxbElementProperty(); + source.setProp( createJakartaJaxb( "5" ) ); + source.publicProp = createJakartaJaxb( "5" ); + + BigDecimalProperty target = JakartaJaxbMapper.INSTANCE.mapBD( source ); + assertThat( target ).isNotNull(); + assertThat( target.getProp() ).isEqualTo( new BigDecimal( "5" ) ); + assertThat( target.publicProp ).isEqualTo( new BigDecimal( "5" ) ); + + JakartaJaxbElementProperty source2 = new JakartaJaxbElementProperty(); + source2.setProp( createJakartaJaxb( "5" ) ); + source2.publicProp = createJakartaJaxb( "5" ); + + SomeTypeProperty target2 = JakartaJaxbMapper.INSTANCE.mapSomeType( source2 ); + assertThat( target2 ).isNotNull(); + assertThat( target2.publicProp ).isNotNull(); + assertThat( target2.getProp() ).isNotNull(); + } + + @ProcessorTest + @WithClasses( { + JaxbListMapper.class, + JaxbElementListProperty.class, + } ) + @WithJavaxJaxb @IssueKey( "141" ) - public void shouldApplyBuiltInOnJAXBElementList() throws ParseException, DatatypeConfigurationException { + public void shouldApplyBuiltInOnJAXBElementList() { JaxbElementListProperty source = new JaxbElementListProperty(); source.setProp( createJaxbList( "TEST2" ) ); @@ -156,8 +196,27 @@ public void shouldApplyBuiltInOnJAXBElementList() throws ParseException, Datatyp assertThat( target.publicProp.get( 0 ) ).isEqualTo( "PUBLIC TEST2" ); } - @Test - public void shouldApplyBuiltInOnDateToXmlGregCal() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( { + JakartaJaxbListMapper.class, + JakartaJaxbElementListProperty.class, + } ) + @WithJakartaJaxb + @IssueKey( "141" ) + public void shouldApplyBuiltInOnJakartaJAXBElementList() { + JakartaJaxbElementListProperty source = new JakartaJaxbElementListProperty(); + source.setProp( createJakartaJaxbList( "TEST2" ) ); + source.publicProp = createJakartaJaxbList( "PUBLIC TEST2" ); + + StringListProperty target = JakartaJaxbListMapper.INSTANCE.map( source ); + assertThat( target ).isNotNull(); + assertThat( target.getProp().get( 0 ) ).isEqualTo( "TEST2" ); + assertThat( target.publicProp.get( 0 ) ).isEqualTo( "PUBLIC TEST2" ); + } + + @ProcessorTest + @WithClasses( DateToXmlGregCalMapper.class ) + public void shouldApplyBuiltInOnDateToXmlGregCal() throws ParseException { DateProperty source = new DateProperty(); source.setProp( createDate( "31-08-1982 10:20:56" ) ); @@ -171,8 +230,9 @@ public void shouldApplyBuiltInOnDateToXmlGregCal() throws ParseException, Dataty assertThat( target.publicProp.toString() ).isEqualTo( "2016-08-31T10:20:56.000+02:00" ); } - @Test - public void shouldApplyBuiltInOnXmlGregCalToDate() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( XmlGregCalToDateMapper.class ) + public void shouldApplyBuiltInOnXmlGregCalToDate() throws DatatypeConfigurationException { XmlGregorianCalendarProperty source = new XmlGregorianCalendarProperty(); source.setProp( createXmlCal( 1999, 3, 2, 60 ) ); @@ -187,8 +247,9 @@ public void shouldApplyBuiltInOnXmlGregCalToDate() throws ParseException, Dataty } - @Test - public void shouldApplyBuiltInStringToXmlGregCal() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( StringToXmlGregCalMapper.class ) + public void shouldApplyBuiltInStringToXmlGregCal() { StringProperty source = new StringProperty(); source.setProp( "05.07.1999" ); @@ -221,8 +282,9 @@ public void shouldApplyBuiltInStringToXmlGregCal() throws ParseException, Dataty } - @Test - public void shouldApplyBuiltInXmlGregCalToString() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( XmlGregCalToStringMapper.class ) + public void shouldApplyBuiltInXmlGregCalToString() throws DatatypeConfigurationException { XmlGregorianCalendarProperty source = new XmlGregorianCalendarProperty(); source.setProp( createXmlCal( 1999, 3, 2, 60 ) ); @@ -247,8 +309,9 @@ public void shouldApplyBuiltInXmlGregCalToString() throws ParseException, Dataty } - @Test - public void shouldApplyBuiltInOnCalendarToXmlGregCal() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( CalendarToXmlGregCalMapper.class ) + public void shouldApplyBuiltInOnCalendarToXmlGregCal() throws ParseException { CalendarProperty source = new CalendarProperty(); source.setProp( createCalendar( "02.03.1999" ) ); @@ -262,8 +325,9 @@ public void shouldApplyBuiltInOnCalendarToXmlGregCal() throws ParseException, Da assertThat( target.publicProp.toString() ).isEqualTo( "2016-03-02T00:00:00.000+01:00" ); } - @Test - public void shouldApplyBuiltInOnXmlGregCalToCalendar() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( XmlGregCalToCalendarMapper.class ) + public void shouldApplyBuiltInOnXmlGregCalToCalendar() throws DatatypeConfigurationException { XmlGregorianCalendarProperty source = new XmlGregorianCalendarProperty(); source.setProp( createXmlCal( 1999, 3, 2, 60 ) ); @@ -279,8 +343,9 @@ public void shouldApplyBuiltInOnXmlGregCalToCalendar() throws ParseException, Da } - @Test - public void shouldApplyBuiltInOnCalendarToDate() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( CalendarToDateMapper.class ) + public void shouldApplyBuiltInOnCalendarToDate() throws ParseException { CalendarProperty source = new CalendarProperty(); source.setProp( createCalendar( "02.03.1999" ) ); @@ -294,8 +359,9 @@ public void shouldApplyBuiltInOnCalendarToDate() throws ParseException, Datatype assertThat( target.publicProp ).isEqualTo( createCalendar( "02.03.2016" ).getTime() ); } - @Test - public void shouldApplyBuiltInOnDateToCalendar() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( DateToCalendarMapper.class ) + public void shouldApplyBuiltInOnDateToCalendar() throws ParseException { DateProperty source = new DateProperty(); source.setProp( new SimpleDateFormat( "dd.MM.yyyy" ).parse( "02.03.1999" ) ); @@ -310,8 +376,9 @@ public void shouldApplyBuiltInOnDateToCalendar() throws ParseException, Datatype } - @Test - public void shouldApplyBuiltInOnCalendarToString() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( CalendarToStringMapper.class ) + public void shouldApplyBuiltInOnCalendarToString() throws ParseException { CalendarProperty source = new CalendarProperty(); source.setProp( createCalendar( "02.03.1999" ) ); @@ -325,8 +392,9 @@ public void shouldApplyBuiltInOnCalendarToString() throws ParseException, Dataty assertThat( target.publicProp ).isEqualTo( "02.03.2016" ); } - @Test - public void shouldApplyBuiltInOnStringToCalendar() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( StringToCalendarMapper.class ) + public void shouldApplyBuiltInOnStringToCalendar() throws ParseException { StringProperty source = new StringProperty(); source.setProp( "02.03.1999" ); @@ -341,12 +409,13 @@ public void shouldApplyBuiltInOnStringToCalendar() throws ParseException, Dataty } - @Test - public void shouldApplyBuiltInOnIterable() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( IterableSourceTargetMapper.class ) + public void shouldApplyBuiltInOnIterable() throws DatatypeConfigurationException { IterableSource source = new IterableSource(); - source.setDates( Arrays.asList( new XMLGregorianCalendar[] { createXmlCal( 1999, 3, 2, 60 ) } ) ); - source.publicDates = Arrays.asList( new XMLGregorianCalendar[] { createXmlCal( 2016, 3, 2, 60 ) } ); + source.setDates( Arrays.asList( createXmlCal( 1999, 3, 2, 60 ) ) ); + source.publicDates = Arrays.asList( createXmlCal( 2016, 3, 2, 60 ) ); IterableTarget target = IterableSourceTargetMapper.INSTANCE.sourceToTarget( source ); assertThat( target ).isNotNull(); @@ -354,13 +423,18 @@ public void shouldApplyBuiltInOnIterable() throws ParseException, DatatypeConfig assertThat( target.publicDates ).containsExactly( "02.03.2016" ); } - @Test - public void shouldApplyBuiltInOnMap() throws ParseException, DatatypeConfigurationException { + @ProcessorTest + @WithClasses( { + MapSourceTargetMapper.class, + MapSource.class, + } ) + @WithJavaxJaxb + public void shouldApplyBuiltInOnMap() throws DatatypeConfigurationException { MapSource source = new MapSource(); - source.setExample( new HashMap, XMLGregorianCalendar>() ); + source.setExample( new HashMap<>() ); source.getExample().put( createJaxb( "TEST" ), createXmlCal( 1999, 3, 2, 60 ) ); - source.publicExample = new HashMap, XMLGregorianCalendar>(); + source.publicExample = new HashMap<>(); source.publicExample.put( createJaxb( "TEST" ), createXmlCal( 2016, 3, 2, 60 ) ); MapTarget target = MapSourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -369,7 +443,8 @@ public void shouldApplyBuiltInOnMap() throws ParseException, DatatypeConfigurati assertThat( target.publicExample.get( "TEST" ) ).isEqualTo( "2016-03-02+01:00" ); } - @Test + @ProcessorTest + @WithClasses( CalendarToZonedDateTimeMapper.class ) public void shouldApplyBuiltInOnCalendarToZonedDateTime() throws ParseException { assertThat( CalendarToZonedDateTimeMapper.INSTANCE.map( null ) ).isNull(); @@ -385,7 +460,8 @@ public void shouldApplyBuiltInOnCalendarToZonedDateTime() throws ParseException assertThat( target.publicProp ).isEqualTo( ZonedDateTime.of( 2016, 3, 2, 0, 0, 0, 0, ZoneId.systemDefault() ) ); } - @Test + @ProcessorTest + @WithClasses( ZonedDateTimeToCalendarMapper.class ) public void shouldApplyBuiltInOnZonedDateTimeToCalendar() throws ParseException { assertThat( ZonedDateTimeToCalendarMapper.INSTANCE.map( null ) ).isNull(); @@ -402,15 +478,25 @@ public void shouldApplyBuiltInOnZonedDateTimeToCalendar() throws ParseException } private JAXBElement createJaxb(String test) { - return new JAXBElement( new QName( "www.mapstruct.org", "test" ), String.class, test ); + return new JAXBElement<>( new QName( "www.mapstruct.org", "test" ), String.class, test ); + } + + private jakarta.xml.bind.JAXBElement createJakartaJaxb(String test) { + return new jakarta.xml.bind.JAXBElement<>( new QName( "www.mapstruct.org", "test" ), String.class, test ); } private List> createJaxbList(String test) { - List> result = new ArrayList>(); + List> result = new ArrayList<>(); result.add( createJaxb( test ) ); return result; } + private List> createJakartaJaxbList(String test) { + List> result = new ArrayList<>(); + result.add( createJakartaJaxb( test ) ); + return result; + } + private Date createDate(String date) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" ); return sdf.parse( date ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/DatatypeFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/DatatypeFactoryTest.java new file mode 100644 index 0000000000..1db8d3abcf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/DatatypeFactoryTest.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +import org.junitpioneer.jupiter.DefaultTimeZone; +import org.mapstruct.ap.test.builtin.bean.CalendarProperty; +import org.mapstruct.ap.test.builtin.bean.DatatypeFactory; +import org.mapstruct.ap.test.builtin.bean.DateProperty; +import org.mapstruct.ap.test.builtin.bean.XmlGregorianCalendarFactorizedProperty; +import org.mapstruct.ap.test.builtin.mapper.ToXmlGregCalMapper; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses( { + DatatypeFactory.class, + XmlGregorianCalendarFactorizedProperty.class, + ToXmlGregCalMapper.class, + CalendarProperty.class, + DateProperty.class + +} ) +@DefaultTimeZone("Europe/Berlin") +public class DatatypeFactoryTest { + + @ProcessorTest + public void testNoConflictsWithOwnDatatypeFactory() throws ParseException { + + DateProperty source1 = new DateProperty(); + source1.setProp( createDate( "31-08-1982 10:20:56" ) ); + + CalendarProperty source2 = new CalendarProperty(); + source2.setProp( createCalendar( "02.03.1999" ) ); + + XmlGregorianCalendarFactorizedProperty target1 = ToXmlGregCalMapper.INSTANCE.map( source1 ); + assertThat( target1 ).isNotNull(); + assertThat( target1.getProp() ).isNotNull(); + assertThat( target1.getProp().toString() ).isEqualTo( "1982-08-31T10:20:56.000+02:00" ); + + XmlGregorianCalendarFactorizedProperty target2 = ToXmlGregCalMapper.INSTANCE.map( source2 ); + assertThat( target2 ).isNotNull(); + assertThat( target2.getProp() ).isNotNull(); + assertThat( target2.getProp().toString() ).isEqualTo( "1999-03-02T00:00:00.000+01:00" ); + + } + + private Date createDate(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" ); + return sdf.parse( date ); + } + + private Calendar createCalendar(String cal) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat( "dd.MM.yyyy" ); + GregorianCalendar gcal = new GregorianCalendar(); + gcal.setTime( sdf.parse( cal ) ); + return gcal; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/IterableTarget.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/IterableTarget.java index b3467c0245..bf43900e6b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/IterableTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/IterableTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/MapTarget.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/MapTarget.java index 4c33ce465a..b280ddc61d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/MapTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/_target/MapTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/BigDecimalProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/BigDecimalProperty.java new file mode 100644 index 0000000000..85e92f7c4d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/BigDecimalProperty.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +import java.math.BigDecimal; + +public class BigDecimalProperty { + + // CHECKSTYLE:OFF + public BigDecimal publicProp; + // CHECKSTYLE:ON + + private BigDecimal prop; + + public BigDecimal getProp() { + return prop; + } + + public void setProp( BigDecimal prop ) { + this.prop = prop; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/CalendarProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/CalendarProperty.java index 90bd0f2299..8ff72ea59c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/CalendarProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/CalendarProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DatatypeFactory.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DatatypeFactory.java new file mode 100644 index 0000000000..648905677c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DatatypeFactory.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +public class DatatypeFactory { + + public XmlGregorianCalendarFactorizedProperty create() { + return new XmlGregorianCalendarFactorizedProperty( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DateProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DateProperty.java index 912ca6f98c..8ace868dad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DateProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/DateProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementListProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementListProperty.java new file mode 100644 index 0000000000..f6ab537253 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementListProperty.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +import java.util.List; + +import jakarta.xml.bind.JAXBElement; + +public class JakartaJaxbElementListProperty { + + // CHECKSTYLE:OFF + public List> publicProp; + // CHECKSTYLE:ON + + private List> prop; + + public List> getProp() { + return prop; + } + + public void setProp( List> prop ) { + this.prop = prop; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementProperty.java new file mode 100644 index 0000000000..0336afe814 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JakartaJaxbElementProperty.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +import jakarta.xml.bind.JAXBElement; + +public class JakartaJaxbElementProperty { + + // CHECKSTYLE:OFF + public JAXBElement publicProp; + // CHECKSTYLE:ON + + private JAXBElement prop; + + public JAXBElement getProp() { + return prop; + } + + public void setProp( JAXBElement prop ) { + this.prop = prop; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementListProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementListProperty.java index 321b32b493..f69655b618 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementListProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementListProperty.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; import java.util.List; - import javax.xml.bind.JAXBElement; public class JaxbElementListProperty { diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementProperty.java index 3c0c616c6f..c981ab613c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/JaxbElementProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/SomeType.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/SomeType.java new file mode 100644 index 0000000000..9ba2a38166 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/SomeType.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +public class SomeType { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/SomeTypeProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/SomeTypeProperty.java new file mode 100644 index 0000000000..fa40da83a4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/SomeTypeProperty.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +public class SomeTypeProperty { + + // CHECKSTYLE:OFF + public SomeType publicProp; + // CHECKSTYLE:ON + + private SomeType prop; + + public SomeType getProp() { + return prop; + } + + public void setProp( SomeType prop ) { + this.prop = prop; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringListProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringListProperty.java index effcfea81b..4cc073ccd0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringListProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringListProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringProperty.java index b7063cfd93..218ce61553 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/StringProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarFactorizedProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarFactorizedProperty.java new file mode 100644 index 0000000000..afbea20a79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarFactorizedProperty.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.bean; + +import javax.xml.datatype.XMLGregorianCalendar; + +public class XmlGregorianCalendarFactorizedProperty { + + private XMLGregorianCalendar prop; + private String control; + + XmlGregorianCalendarFactorizedProperty( String in ) { + this.control = in; + } + + public XMLGregorianCalendar getProp() { + return prop; + } + + public void setProp( XMLGregorianCalendar prop ) { + this.prop = prop; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarProperty.java index bb165acb6e..c15a62eb9c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/bean/XmlGregorianCalendarProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/bean/ZonedDateTimeProperty.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/bean/ZonedDateTimeProperty.java index ee391ff135..467f553077 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/bean/ZonedDateTimeProperty.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/bean/ZonedDateTimeProperty.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.java8time.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/CalendarToZonedDateTimeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/CalendarToZonedDateTimeMapper.java index ec2be5bf15..8c860ce319 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/CalendarToZonedDateTimeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/CalendarToZonedDateTimeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.java8time.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/ZonedDateTimeToCalendarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/ZonedDateTimeToCalendarMapper.java index b1281c111f..5034a05db4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/ZonedDateTimeToCalendarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/java8time/mapper/ZonedDateTimeToCalendarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.java8time.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/JodaTimeTest.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/JodaTimeTest.java index 6d4cc75928..cb0c3d2378 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/JodaTimeTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/JodaTimeTest.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime; -import static org.assertj.core.api.Assertions.assertThat; - import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; @@ -29,8 +14,6 @@ import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.builtin.jodatime.bean.DateTimeBean; import org.mapstruct.ap.test.builtin.jodatime.bean.LocalDateBean; import org.mapstruct.ap.test.builtin.jodatime.bean.LocalDateTimeBean; @@ -45,8 +28,12 @@ import org.mapstruct.ap.test.builtin.jodatime.mapper.XmlGregorianCalendarToLocalDateTime; import org.mapstruct.ap.test.builtin.jodatime.mapper.XmlGregorianCalendarToLocalTime; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxJaxb; +import org.mapstruct.ap.testutil.WithJoda; + +import static org.assertj.core.api.Assertions.assertThat; /** * @@ -59,11 +46,12 @@ LocalDateTimeBean.class, XmlGregorianCalendarBean.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey( "689" ) +@WithJoda +@WithJavaxJaxb public class JodaTimeTest { - @Test + @ProcessorTest @WithClasses(DateTimeToXmlGregorianCalendar.class) public void shouldMapDateTimeToXmlGregorianCalendar() { @@ -82,7 +70,7 @@ public void shouldMapDateTimeToXmlGregorianCalendar() { assertThat( res.getxMLGregorianCalendar().getTimezone() ).isEqualTo( -60 ); } - @Test + @ProcessorTest @WithClasses(DateTimeToXmlGregorianCalendar.class) public void shouldMapIncompleteDateTimeToXmlGregorianCalendar() { @@ -98,7 +86,7 @@ public void shouldMapIncompleteDateTimeToXmlGregorianCalendar() { assertThat( res.getxMLGregorianCalendar().getMinute() ).isEqualTo( 1 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldMapXmlGregorianCalendarToDateTime() throws Exception { @@ -118,7 +106,7 @@ public void shouldMapXmlGregorianCalendarToDateTime() throws Exception { assertThat( res.getDateTime().getZone().getOffset( null ) ).isEqualTo( 3600000 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldMapXmlGregorianCalendarWithoutTimeZoneToDateTimeWithDefaultTimeZone() throws Exception { @@ -144,7 +132,7 @@ public void shouldMapXmlGregorianCalendarWithoutTimeZoneToDateTimeWithDefaultTim assertThat( res.getDateTime().getZone().getOffset( 0 ) ).isEqualTo( DateTimeZone.getDefault().getOffset( 0 ) ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldMapXmlGregorianCalendarWithoutMillisToDateTime() throws Exception { @@ -170,7 +158,7 @@ public void shouldMapXmlGregorianCalendarWithoutMillisToDateTime() throws Except assertThat( res.getDateTime().getZone().getOffset( null ) ).isEqualTo( 3600000 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldMapXmlGregorianCalendarWithoutMillisAndTimeZoneToDateTimeWithDefaultTimeZone() throws Exception { @@ -195,7 +183,7 @@ public void shouldMapXmlGregorianCalendarWithoutMillisAndTimeZoneToDateTimeWithD assertThat( res.getDateTime().getZone().getOffset( 0 ) ).isEqualTo( DateTimeZone.getDefault().getOffset( 0 ) ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldMapXmlGregorianCalendarWithoutSecondsToDateTime() throws Exception { @@ -220,7 +208,7 @@ public void shouldMapXmlGregorianCalendarWithoutSecondsToDateTime() throws Excep assertThat( res.getDateTime().getZone().getOffset( null ) ).isEqualTo( 3600000 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldMapXmlGregorianCalendarWithoutSecondsAndTimeZoneToDateTimeWithDefaultTimeZone() throws Exception { @@ -244,7 +232,7 @@ public void shouldMapXmlGregorianCalendarWithoutSecondsAndTimeZoneToDateTimeWith assertThat( res.getDateTime().getZone().getOffset( 0 ) ).isEqualTo( DateTimeZone.getDefault().getOffset( 0 ) ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToDateTime.class) public void shouldNotMapXmlGregorianCalendarWithoutMinutes() throws Exception { @@ -260,7 +248,7 @@ public void shouldNotMapXmlGregorianCalendarWithoutMinutes() throws Exception { assertThat( res.getDateTime() ).isNull(); } - @Test + @ProcessorTest @WithClasses({DateTimeToXmlGregorianCalendar.class, XmlGregorianCalendarToDateTime.class}) public void shouldMapRoundTrip() { @@ -276,7 +264,7 @@ public void shouldMapRoundTrip() { } - @Test + @ProcessorTest @WithClasses(LocalDateTimeToXmlGregorianCalendar.class) public void shouldMapLocalDateTimeToXmlGregorianCalendar() { @@ -295,7 +283,7 @@ public void shouldMapLocalDateTimeToXmlGregorianCalendar() { assertThat( res.getxMLGregorianCalendar().getTimezone() ).isEqualTo( DatatypeConstants.FIELD_UNDEFINED ); } - @Test + @ProcessorTest @WithClasses(LocalDateTimeToXmlGregorianCalendar.class) public void shouldMapIncompleteLocalDateTimeToXmlGregorianCalendar() { @@ -314,7 +302,7 @@ public void shouldMapIncompleteLocalDateTimeToXmlGregorianCalendar() { assertThat( res.getxMLGregorianCalendar().getTimezone() ).isEqualTo( DatatypeConstants.FIELD_UNDEFINED ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalDateTime.class) public void shouldMapXmlGregorianCalendarToLocalDateTime() throws Exception { @@ -333,7 +321,7 @@ public void shouldMapXmlGregorianCalendarToLocalDateTime() throws Exception { assertThat( res.getLocalDateTime().getMillisOfSecond() ).isEqualTo( 100 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalDateTime.class) public void shouldMapXmlGregorianCalendarWithoutMillisToLocalDateTime() throws Exception { @@ -357,7 +345,7 @@ public void shouldMapXmlGregorianCalendarWithoutMillisToLocalDateTime() throws E assertThat( res.getLocalDateTime().getMillisOfSecond() ).isEqualTo( 0 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalDateTime.class) public void shouldMapXmlGregorianCalendarWithoutSecondsToLocalDateTime() throws Exception { @@ -381,7 +369,7 @@ public void shouldMapXmlGregorianCalendarWithoutSecondsToLocalDateTime() throws assertThat( res.getLocalDateTime().getMillisOfSecond() ).isEqualTo( 0 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalDateTime.class) public void shouldNotMapXmlGregorianCalendarWithoutMinutesToLocalDateTime() throws Exception { @@ -398,7 +386,7 @@ public void shouldNotMapXmlGregorianCalendarWithoutMinutesToLocalDateTime() thro } - @Test + @ProcessorTest @WithClasses(LocalDateToXmlGregorianCalendar.class) public void shouldMapLocalDateToXmlGregorianCalendar() { @@ -417,7 +405,7 @@ public void shouldMapLocalDateToXmlGregorianCalendar() { assertThat( res.getxMLGregorianCalendar().getTimezone() ).isEqualTo( DatatypeConstants.FIELD_UNDEFINED ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalDate.class) public void shouldMapXmlGregorianCalendarToLocalDate() throws Exception { @@ -435,7 +423,7 @@ public void shouldMapXmlGregorianCalendarToLocalDate() throws Exception { assertThat( res.getLocalDate().getDayOfMonth() ).isEqualTo( 25 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalDate.class) public void shouldNotMapXmlGregorianCalendarWithoutDaysToLocalDate() throws Exception { @@ -452,7 +440,7 @@ public void shouldNotMapXmlGregorianCalendarWithoutDaysToLocalDate() throws Exce } - @Test + @ProcessorTest @WithClasses(LocalTimeToXmlGregorianCalendar.class) public void shouldMapIncompleteLocalTimeToXmlGregorianCalendar() { @@ -471,7 +459,7 @@ public void shouldMapIncompleteLocalTimeToXmlGregorianCalendar() { assertThat( res.getxMLGregorianCalendar().getTimezone() ).isEqualTo( DatatypeConstants.FIELD_UNDEFINED ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalTime.class) public void shouldMapXmlGregorianCalendarToLocalTime() throws Exception { @@ -487,7 +475,7 @@ public void shouldMapXmlGregorianCalendarToLocalTime() throws Exception { assertThat( res.getLocalTime().getMillisOfSecond() ).isEqualTo( 100 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalTime.class) public void shouldMapXmlGregorianCalendarWithoutMillisToLocalTime() throws Exception { @@ -505,7 +493,7 @@ public void shouldMapXmlGregorianCalendarWithoutMillisToLocalTime() throws Excep assertThat( res.getLocalTime().getMillisOfSecond() ).isEqualTo( 0 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalTime.class) public void shouldMapXmlGregorianCalendarWithoutSecondsToLocalTime() throws Exception { @@ -523,7 +511,7 @@ public void shouldMapXmlGregorianCalendarWithoutSecondsToLocalTime() throws Exce assertThat( res.getLocalTime().getMillisOfSecond() ).isEqualTo( 0 ); } - @Test + @ProcessorTest @WithClasses(XmlGregorianCalendarToLocalTime.class) public void shouldNotMapXmlGregorianCalendarWithoutMinutesToLocalTime() throws Exception { diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/DateTimeBean.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/DateTimeBean.java index 22f08dac33..e250aa12df 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/DateTimeBean.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/DateTimeBean.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateBean.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateBean.java index 60d553e397..3306964076 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateBean.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateBean.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateTimeBean.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateTimeBean.java index dadebd9d73..d7e968848d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateTimeBean.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalDateTimeBean.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalTimeBean.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalTimeBean.java index f59ab320e6..fd74f507b3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalTimeBean.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/LocalTimeBean.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/XmlGregorianCalendarBean.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/XmlGregorianCalendarBean.java index e87731e3ec..7ba0fd4aed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/XmlGregorianCalendarBean.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/bean/XmlGregorianCalendarBean.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.bean; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/DateTimeToXmlGregorianCalendar.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/DateTimeToXmlGregorianCalendar.java index 459c394c2f..d56a7b5019 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/DateTimeToXmlGregorianCalendar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/DateTimeToXmlGregorianCalendar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateTimeToXmlGregorianCalendar.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateTimeToXmlGregorianCalendar.java index c88ab55231..e36808d608 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateTimeToXmlGregorianCalendar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateTimeToXmlGregorianCalendar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateToXmlGregorianCalendar.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateToXmlGregorianCalendar.java index 1eabb75bda..d9a3b2ce19 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateToXmlGregorianCalendar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalDateToXmlGregorianCalendar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalTimeToXmlGregorianCalendar.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalTimeToXmlGregorianCalendar.java index 2180efc095..74b5ffda71 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalTimeToXmlGregorianCalendar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/LocalTimeToXmlGregorianCalendar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToDateTime.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToDateTime.java index b9b0d8a9a1..a173faacf1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToDateTime.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToDateTime.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDate.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDate.java index d956606100..4fa3f31d49 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDateTime.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDateTime.java index 99ef408481..b5807dfe81 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDateTime.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalDateTime.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalTime.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalTime.java index 17ec485b4a..28d082469f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalTime.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/jodatime/mapper/XmlGregorianCalendarToLocalTime.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.jodatime.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToDateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToDateMapper.java index be052a305a..a0abde8a87 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToDateMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToDateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToStringMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToStringMapper.java index 81626f8b52..da21e10e0e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToStringMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToStringMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToXmlGregCalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToXmlGregCalMapper.java index 17e72ee193..445507a8bb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToXmlGregCalMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/CalendarToXmlGregCalMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToCalendarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToCalendarMapper.java index 32794e0d64..fcc04131f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToCalendarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToCalendarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToXmlGregCalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToXmlGregCalMapper.java index 26d4a264c2..9136959ad6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToXmlGregCalMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/DateToXmlGregCalMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/IterableSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/IterableSourceTargetMapper.java index 05b228cd0e..619a72514c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/IterableSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/IterableSourceTargetMapper.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; import java.util.List; - import javax.xml.datatype.XMLGregorianCalendar; import org.mapstruct.IterableMapping; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbListMapper.java new file mode 100644 index 0000000000..602e2180f1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbListMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementListProperty; +import org.mapstruct.ap.test.builtin.bean.StringListProperty; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface JakartaJaxbListMapper { + + JakartaJaxbListMapper INSTANCE = Mappers.getMapper( JakartaJaxbListMapper.class ); + + StringListProperty map(JakartaJaxbElementListProperty source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbMapper.java new file mode 100644 index 0000000000..9334792572 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JakartaJaxbMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.builtin.bean.BigDecimalProperty; +import org.mapstruct.ap.test.builtin.bean.JakartaJaxbElementProperty; +import org.mapstruct.ap.test.builtin.bean.SomeType; +import org.mapstruct.ap.test.builtin.bean.SomeTypeProperty; +import org.mapstruct.ap.test.builtin.bean.StringProperty; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface JakartaJaxbMapper { + + JakartaJaxbMapper INSTANCE = Mappers.getMapper( JakartaJaxbMapper.class ); + + StringProperty map(JakartaJaxbElementProperty source); + + BigDecimalProperty mapBD(JakartaJaxbElementProperty source); + + SomeTypeProperty mapSomeType(JakartaJaxbElementProperty source); + + @SuppressWarnings( "unused" ) + default SomeType map( String in ) { + return new SomeType(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbListMapper.java index e4ebcddb3b..c34d956a2d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbListMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbMapper.java index b97689c637..ec2ca65b29 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/JaxbMapper.java @@ -1,25 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; import org.mapstruct.Mapper; +import org.mapstruct.ap.test.builtin.bean.BigDecimalProperty; import org.mapstruct.ap.test.builtin.bean.JaxbElementProperty; +import org.mapstruct.ap.test.builtin.bean.SomeType; +import org.mapstruct.ap.test.builtin.bean.SomeTypeProperty; import org.mapstruct.ap.test.builtin.bean.StringProperty; import org.mapstruct.factory.Mappers; @@ -29,4 +19,12 @@ public interface JaxbMapper { JaxbMapper INSTANCE = Mappers.getMapper( JaxbMapper.class ); StringProperty map(JaxbElementProperty source); + + BigDecimalProperty mapBD(JaxbElementProperty source); + + SomeTypeProperty mapSomeType(JaxbElementProperty source); + + default SomeType map( String in ) { + return new SomeType(); + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/MapSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/MapSourceTargetMapper.java index e7e2f14632..04a8f6bf0d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/MapSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/MapSourceTargetMapper.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; import java.util.Map; - import javax.xml.bind.JAXBElement; import javax.xml.datatype.XMLGregorianCalendar; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToCalendarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToCalendarMapper.java index 385cebd2e5..31e782976e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToCalendarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToCalendarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToXmlGregCalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToXmlGregCalMapper.java index 3880f96b6b..a216b0b262 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToXmlGregCalMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/StringToXmlGregCalMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/ToXmlGregCalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/ToXmlGregCalMapper.java new file mode 100644 index 0000000000..9ab5dc366a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/ToXmlGregCalMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.builtin.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.builtin.bean.CalendarProperty; +import org.mapstruct.ap.test.builtin.bean.DatatypeFactory; +import org.mapstruct.ap.test.builtin.bean.DateProperty; +import org.mapstruct.ap.test.builtin.bean.XmlGregorianCalendarFactorizedProperty; +import org.mapstruct.factory.Mappers; + +@Mapper( uses = DatatypeFactory.class ) +public interface ToXmlGregCalMapper { + + ToXmlGregCalMapper INSTANCE = Mappers.getMapper( ToXmlGregCalMapper.class ); + + XmlGregorianCalendarFactorizedProperty map(CalendarProperty source); + + XmlGregorianCalendarFactorizedProperty map(DateProperty source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToCalendarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToCalendarMapper.java index e36b273ff3..29835c39b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToCalendarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToCalendarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToDateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToDateMapper.java index b942602dfa..8b6eca9512 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToDateMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToDateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToStringMapper.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToStringMapper.java index df6e94cccd..69d1ddc961 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToStringMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/mapper/XmlGregCalToStringMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.mapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/source/IterableSource.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/source/IterableSource.java index 824d238a2a..69a3bab2bc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/source/IterableSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/source/IterableSource.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.source; import java.util.List; - import javax.xml.datatype.XMLGregorianCalendar; /** diff --git a/processor/src/test/java/org/mapstruct/ap/test/builtin/source/MapSource.java b/processor/src/test/java/org/mapstruct/ap/test/builtin/source/MapSource.java index f77cb7471b..6b8e8f3b94 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/builtin/source/MapSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/builtin/source/MapSource.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.builtin.source; import java.util.Map; - import javax.xml.bind.JAXBElement; import javax.xml.datatype.XMLGregorianCalendar; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java index cf37085c5a..4e02045ed5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/BaseMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; @@ -34,7 +21,10 @@ public abstract class BaseMapper { public abstract Target sourceToTarget(Source source); - private static final List INVOCATIONS = new ArrayList(); + @Qualified + public abstract Target sourceToTargetQualified(Source source); + + private static final List INVOCATIONS = new ArrayList<>(); @BeforeMapping public void noArgsBeforeMapping() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java index 5a72f807fa..825b359152 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/CallbackMethodTest.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -27,34 +12,33 @@ import java.util.List; import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.BeforeEach; import org.mapstruct.AfterMapping; import org.mapstruct.BeforeMapping; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for callback methods that are defined using {@link BeforeMapping} / {@link AfterMapping} * * @author Andreas Gudian */ -@RunWith( AnnotationProcessorTestRunner.class ) @WithClasses( { ClassContainingCallbacks.class, Invocation.class, Source.class, Target.class, SourceTargetMapper.class, SourceTargetCollectionMapper.class, BaseMapper.class, Qualified.class, SourceEnum.class, TargetEnum.class }) @IssueKey("14") public class CallbackMethodTest { - @Before + @BeforeEach public void reset() { ClassContainingCallbacks.reset(); BaseMapper.reset(); } - @Test + @ProcessorTest public void callbackMethodsForBeanMappingCalled() { SourceTargetMapper.INSTANCE.sourceToTarget( createSource() ); @@ -62,7 +46,7 @@ public void callbackMethodsForBeanMappingCalled() { assertBeanMappingInvocations( BaseMapper.getInvocations() ); } - @Test + @ProcessorTest public void callbackMethodsForBeanMappingWithResultParamCalled() { SourceTargetMapper.INSTANCE.sourceToTarget( createSource(), createEmptyTarget() ); @@ -70,7 +54,7 @@ public void callbackMethodsForBeanMappingWithResultParamCalled() { assertBeanMappingInvocations( BaseMapper.getInvocations() ); } - @Test + @ProcessorTest public void callbackMethodsForIterableMappingCalled() { SourceTargetCollectionMapper.INSTANCE.sourceToTarget( Arrays.asList( createSource() ) ); @@ -78,16 +62,16 @@ public void callbackMethodsForIterableMappingCalled() { assertIterableMappingInvocations( BaseMapper.getInvocations() ); } - @Test + @ProcessorTest public void callbackMethodsForIterableMappingWithResultParamCalled() { SourceTargetCollectionMapper.INSTANCE.sourceToTarget( - Arrays.asList( createSource() ), new ArrayList() ); + Arrays.asList( createSource() ), new ArrayList<>() ); assertIterableMappingInvocations( ClassContainingCallbacks.getInvocations() ); assertIterableMappingInvocations( BaseMapper.getInvocations() ); } - @Test + @ProcessorTest public void callbackMethodsForMapMappingCalled() { SourceTargetCollectionMapper.INSTANCE.sourceToTarget( toMap( "foo", createSource() ) ); @@ -95,17 +79,17 @@ public void callbackMethodsForMapMappingCalled() { assertMapMappingInvocations( BaseMapper.getInvocations() ); } - @Test + @ProcessorTest public void callbackMethodsForMapMappingWithResultParamCalled() { SourceTargetCollectionMapper.INSTANCE.sourceToTarget( toMap( "foo", createSource() ), - new HashMap() ); + new HashMap<>() ); assertMapMappingInvocations( ClassContainingCallbacks.getInvocations() ); assertMapMappingInvocations( BaseMapper.getInvocations() ); } - @Test + @ProcessorTest public void qualifiersAreEvaluatedCorrectly() { Source source = createSource(); Target target = SourceTargetMapper.INSTANCE.qualifiedSourceToTarget( source ); @@ -122,12 +106,12 @@ public void qualifiersAreEvaluatedCorrectly() { assertQualifiedInvocations( BaseMapper.getInvocations(), sourceList, targetList ); } - @Test + @ProcessorTest public void callbackMethodsForEnumMappingCalled() { SourceEnum source = SourceEnum.B; TargetEnum target = SourceTargetMapper.INSTANCE.toTargetEnum( source ); - List invocations = new ArrayList(); + List invocations = new ArrayList<>(); invocations.addAll( allBeforeMappingMethods( source, target, TargetEnum.class ) ); invocations.addAll( allAfterMappingMethods( source, target, TargetEnum.class ) ); @@ -186,7 +170,7 @@ private void assertMapMappingInvocations(List invocations) { } private Map toMap(String string, T value) { - Map result = new HashMap(); + Map result = new HashMap<>(); result.put( string, value ); return result; } @@ -204,7 +188,7 @@ private void assertCollectionMappingInvocations(List invocations, Ob } private List beanMappingInvocationList(Object source, Object target, Object emptyTarget) { - List invocations = new ArrayList(); + List invocations = new ArrayList<>(); invocations.addAll( allBeforeMappingMethods( source, emptyTarget, Target.class ) ); invocations.addAll( allAfterMappingMethods( source, target, Target.class ) ); @@ -213,7 +197,7 @@ private List beanMappingInvocationList(Object source, Object target, } private List allAfterMappingMethods(Object source, Object target, Class targetClass) { - return new ArrayList( Arrays.asList( + return new ArrayList<>( Arrays.asList( new Invocation( "noArgsAfterMapping" ), new Invocation( "withSourceAfterMapping", source ), new Invocation( "withSourceAsObjectAfterMapping", source ), @@ -224,7 +208,7 @@ private List allAfterMappingMethods(Object source, Object target, Cl } private List allBeforeMappingMethods(Object source, Object emptyTarget, Class targetClass) { - return new ArrayList( Arrays.asList( + return new ArrayList<>( Arrays.asList( new Invocation( "noArgsBeforeMapping" ), new Invocation( "withSourceBeforeMapping", source ), new Invocation( "withSourceAsObjectBeforeMapping", source ), @@ -239,7 +223,7 @@ private void assertQualifiedInvocations(List actual, Object source, } private List allQualifiedCallbackMethods(Object source, Object target) { - List invocations = new ArrayList(); + List invocations = new ArrayList<>(); invocations.add( new Invocation( "withSourceBeforeMappingQualified", source ) ); if ( source instanceof List || source instanceof Map ) { diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java index 5c37663fae..2889a4ad30 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ClassContainingCallbacks.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; @@ -31,7 +18,7 @@ * @author Andreas Gudian */ public class ClassContainingCallbacks { - private static final List INVOCATIONS = new ArrayList(); + private static final List INVOCATIONS = new ArrayList<>(); @BeforeMapping public void noArgsBeforeMapping() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Invocation.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Invocation.java index 9a560294fa..42d321af7c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Invocation.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Invocation.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; @@ -75,13 +62,10 @@ else if ( !arguments.equals( other.arguments ) ) { return false; } if ( methodName == null ) { - if ( other.methodName != null ) { - return false; - } + return other.methodName == null; } - else if ( !methodName.equals( other.methodName ) ) { - return false; + else { + return methodName.equals( other.methodName ); } - return true; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java index f80a554c7a..1a0f48f4b1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Qualified.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Source.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Source.java index 90f7893ef9..69d91af39d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; @@ -53,14 +40,11 @@ public boolean equals(Object obj) { } Source other = (Source) obj; if ( foo == null ) { - if ( other.foo != null ) { - return false; - } + return other.foo == null; } - else if ( !foo.equals( other.foo ) ) { - return false; + else { + return foo.equals( other.foo ); } - return true; } @Override diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceEnum.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceEnum.java index 25b636cd5e..93e393246a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceEnum.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceEnum.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java index c8f62b5405..2d6996b484 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetCollectionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java index a7824fb7a7..725bbe5c03 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Target.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Target.java index a92f0af080..d800bfbcdc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; @@ -53,14 +40,11 @@ public boolean equals(Object obj) { } Target other = (Target) obj; if ( foo == null ) { - if ( other.foo != null ) { - return false; - } + return other.foo == null; } - else if ( !foo.equals( other.foo ) ) { - return false; + else { + return foo.equals( other.foo ); } - return true; } @Override diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/TargetEnum.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/TargetEnum.java index 65242cbfc6..016be4363f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/TargetEnum.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/TargetEnum.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Address.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Address.java index d56f7cf729..503e57ae25 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Address.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/AddressDto.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/AddressDto.java index 635ea83aa4..4d6a16182c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/AddressDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Company.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Company.java index 88a77ecd38..182568a730 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Company.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Company.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyDto.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyDto.java index 69a7ac6a58..3227a04970 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapper.java index d0c848b092..4296f07791 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java index e202d8b461..bb7f08a836 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/CompanyMapperPostProcessing.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; @@ -30,9 +17,9 @@ public class CompanyMapperPostProcessing { @AfterMapping public void toAddressDto(Address address, @MappingTarget AddressDto addressDto) { String addressLine = address.getAddressLine(); - int seperatorIndex = addressLine.indexOf( ";" ); - addressDto.setStreet( addressLine.substring( 0, seperatorIndex ) ); - String houseNumber = addressLine.substring( seperatorIndex + 1, addressLine.length() ); + int separatorIndex = addressLine.indexOf( ";" ); + addressDto.setStreet( addressLine.substring( 0, separatorIndex ) ); + String houseNumber = addressLine.substring( separatorIndex + 1 ); addressDto.setHouseNumber( Integer.parseInt( houseNumber ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Employee.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Employee.java index 9a685565fc..95a31a47a2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Employee.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/Employee.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/EmployeeDto.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/EmployeeDto.java index 8f41b760e6..55ceeb40ce 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/EmployeeDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/EmployeeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/MappingResultPostprocessorTest.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/MappingResultPostprocessorTest.java index de84c16f29..6ec9ee129d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/MappingResultPostprocessorTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/ongeneratedmethods/MappingResultPostprocessorTest.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.ongeneratedmethods; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @@ -44,10 +29,9 @@ CompanyMapperPostProcessing.class }) @IssueKey("183") -@RunWith(AnnotationProcessorTestRunner.class) public class MappingResultPostprocessorTest { - @Test + @ProcessorTest public void test() { // setup @@ -57,7 +41,7 @@ public void test() { Employee employee = new Employee(); employee.setAddress( address ); Company company = new Company(); - company.setEmployees( Arrays.asList( new Employee[] { employee } ) ); + company.setEmployees( Arrays.asList( employee ) ); // test CompanyDto companyDto = CompanyMapper.INSTANCE.toCompanyDto( company ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Attribute.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Attribute.java index 1fbd761ddb..54d7434a3c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Attribute.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Attribute.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/AttributeDto.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/AttributeDto.java index 4d7e3f1b11..7bb178ae85 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/AttributeDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/AttributeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/CallbacksWithReturnValuesTest.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/CallbacksWithReturnValuesTest.java index c10c4c3d36..10d2a29cd7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/CallbacksWithReturnValuesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/CallbacksWithReturnValuesTest.java @@ -1,34 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; import java.util.concurrent.atomic.AtomicReference; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; import org.mapstruct.ap.test.callbacks.returning.NodeMapperContext.ContextListener; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Test case for https://github.com/mapstruct/mapstruct/issues/469 @@ -39,29 +26,31 @@ @WithClasses( { Attribute.class, AttributeDto.class, Node.class, NodeDto.class, NodeMapperDefault.class, NodeMapperWithContext.class, NodeMapperContext.class, Number.class, NumberMapperDefault.class, NumberMapperContext.class, NumberMapperWithContext.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) -public class CallbacksWithReturnValuesTest { - @Test( expected = StackOverflowError.class ) - public void mappingWithDefaultHandlingRaisesStackOverflowError() { +class CallbacksWithReturnValuesTest { + @AfterEach + void cleanup() { + NumberMapperContext.clearCache(); + NumberMapperContext.clearVisited(); + } + + @ProcessorTest + void mappingWithDefaultHandlingRaisesStackOverflowError() { Node root = buildNodes(); - NodeMapperDefault.INSTANCE.nodeToNodeDto( root ); + assertThatThrownBy( () -> NodeMapperDefault.INSTANCE.nodeToNodeDto( root ) ) + .isInstanceOf( StackOverflowError.class ); } - @Test( expected = StackOverflowError.class ) - public void updatingWithDefaultHandlingRaisesStackOverflowError() { + @ProcessorTest + void updatingWithDefaultHandlingRaisesStackOverflowError() { Node root = buildNodes(); - NodeMapperDefault.INSTANCE.nodeToNodeDto( root, new NodeDto() ); + assertThatThrownBy( () -> NodeMapperDefault.INSTANCE.nodeToNodeDto( root, new NodeDto() ) ) + .isInstanceOf( StackOverflowError.class ); } - @Test - public void mappingWithContextCorrectlyResolvesCycles() { - final AtomicReference contextLevel = new AtomicReference( null ); - ContextListener contextListener = new ContextListener() { - @Override - public void methodCalled(Integer level, String method, Object source, Object target) { - contextLevel.set( level ); - } - }; + @ProcessorTest + void mappingWithContextCorrectlyResolvesCycles() { + final AtomicReference contextLevel = new AtomicReference<>( null ); + ContextListener contextListener = (level, method, source, target) -> contextLevel.set( level ); NodeMapperContext.addContextListener( contextListener ); try { @@ -87,29 +76,50 @@ private static Node buildNodes() { return root; } - @Test - public void numberMappingWithoutContextDoesNotUseCache() { + @ProcessorTest + void numberMappingWithoutContextDoesNotUseCache() { Number n1 = NumberMapperDefault.INSTANCE.integerToNumber( 2342 ); Number n2 = NumberMapperDefault.INSTANCE.integerToNumber( 2342 ); + assertThat( n1 ).isEqualTo( n2 ); assertThat( n1 ).isNotSameAs( n2 ); } - @Test - public void numberMappingWithContextUsesCache() { + @ProcessorTest + void numberMappingWithContextUsesCache() { NumberMapperContext.putCache( new Number( 2342 ) ); Number n1 = NumberMapperWithContext.INSTANCE.integerToNumber( 2342 ); Number n2 = NumberMapperWithContext.INSTANCE.integerToNumber( 2342 ); + assertThat( n1 ).isEqualTo( n2 ); assertThat( n1 ).isSameAs( n2 ); - NumberMapperContext.clearCache(); } - @Test - public void numberMappingWithContextCallsVisitNumber() { + @ProcessorTest + void numberMappingWithContextCallsVisitNumber() { Number n1 = NumberMapperWithContext.INSTANCE.integerToNumber( 1234 ); Number n2 = NumberMapperWithContext.INSTANCE.integerToNumber( 5678 ); + assertThat( NumberMapperContext.getVisited() ).isEqualTo( Arrays.asList( n1, n2 ) ); - NumberMapperContext.clearVisited(); + } + + @ProcessorTest + @IssueKey( "2955" ) + void numberUpdateMappingWithContextUsesCacheAndThereforeDoesNotVisitNumber() { + Number target = new Number(); + Number expectedReturn = new Number( 2342 ); + NumberMapperContext.putCache( expectedReturn ); + NumberMapperWithContext.INSTANCE.integerToNumber( 2342, target ); + + assertThat( NumberMapperContext.getVisited() ).isEmpty(); + } + + @ProcessorTest + @IssueKey( "2955" ) + void numberUpdateMappingWithContextCallsVisitNumber() { + Number target = new Number(); + NumberMapperWithContext.INSTANCE.integerToNumber( 2342, target ); + + assertThat( NumberMapperContext.getVisited() ).contains( target ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Node.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Node.java index e3ef456549..2ee619c61d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Node.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Node.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; @@ -38,8 +25,8 @@ public Node() { public Node(String name) { this.name = name; - this.children = new ArrayList(); - this.attributes = new ArrayList(); + this.children = new ArrayList<>(); + this.attributes = new ArrayList<>(); } public Node getParent() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeDto.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeDto.java index d5ef75a37a..36f7a2e3b1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperContext.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperContext.java index e1f82f5552..325778b85e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; @@ -32,11 +19,11 @@ * @author Pascal Grün */ public class NodeMapperContext { - private static final ThreadLocal LEVEL = new ThreadLocal(); - private static final ThreadLocal> MAPPING = new ThreadLocal>(); + private static final ThreadLocal LEVEL = new ThreadLocal<>(); + private static final ThreadLocal> MAPPING = new ThreadLocal<>(); /** Only for test-inspection */ - private static final List LISTENERS = new CopyOnWriteArrayList(); + private static final List LISTENERS = new CopyOnWriteArrayList<>(); private NodeMapperContext() { // Only allow static access @@ -61,7 +48,7 @@ public static void setInstance(Object source, @MappingTarget Object target) { fireMethodCalled( level, "setInstance", source, target ); if ( level == null ) { LEVEL.set( 1 ); - MAPPING.set( new IdentityHashMap() ); + MAPPING.set( new IdentityHashMap<>() ); } else { LEVEL.set( level + 1 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperDefault.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperDefault.java index f3dfe15a07..f633a63d11 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperDefault.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperDefault.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperWithContext.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperWithContext.java index 8830bea521..456eb1134b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperWithContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NodeMapperWithContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Number.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Number.java index ad7c0bda1d..9edd87025b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Number.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/Number.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperContext.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperContext.java index ddadffa7ad..bbbe9c6bec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; @@ -32,9 +19,9 @@ * @author Pascal Grün */ public class NumberMapperContext { - private static final Map CACHE = new HashMap(); + private static final Map CACHE = new HashMap<>(); - private static final List VISITED = new ArrayList(); + private static final List VISITED = new ArrayList<>(); private NumberMapperContext() { // Only allow static access @@ -58,8 +45,7 @@ public static void clearVisited() { @AfterMapping public static Number getInstance(Integer source, @MappingTarget Number target) { - Number cached = CACHE.get( target ); - return ( cached == null ? null : cached ); + return CACHE.get( target ); } @AfterMapping diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperDefault.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperDefault.java index 13919341f9..d21e67fdb8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperDefault.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperDefault.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperWithContext.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperWithContext.java index 819162e88a..2a1f48e726 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperWithContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/returning/NumberMapperWithContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.returning; diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CallbackMethodTypeMatchingTest.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CallbackMethodTypeMatchingTest.java index 22ea4d620a..ebdca6c04c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CallbackMethodTypeMatchingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CallbackMethodTypeMatchingTest.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.typematching; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.callbacks.typematching.CarMapper.CarDto; import org.mapstruct.ap.test.callbacks.typematching.CarMapper.CarEntity; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian * */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ CarMapper.class }) public class CallbackMethodTypeMatchingTest { - @Test + @ProcessorTest public void callbackMethodAreCalled() { CarEntity carEntity = CarMapper.INSTANCE.toCarEntity( new CarDto() ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CarMapper.java index ba5170570e..2d3105531c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/callbacks/typematching/CarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.callbacks.typematching; diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ClassAccessibilityTest.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ClassAccessibilityTest.java new file mode 100644 index 0000000000..8bac5841f1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ClassAccessibilityTest.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static java.lang.reflect.Modifier.isPrivate; +import static java.lang.reflect.Modifier.isProtected; +import static java.lang.reflect.Modifier.isPublic; +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + Source.class, + Target.class, + PublicAbstractionMapper.class, + PackageAbstractionMapper.class, + ForcedPublicMapper.class, + ForcedPackagePrivateMapper.class +}) +public class ClassAccessibilityTest { + + @ProcessorTest + public void shouldCreateModifierAccordingToAnnotation() throws Exception { + Class publicLike = loadForMapper( PublicAbstractionMapper.class ); + assertThat( isPublic( publicLike.getModifiers() ) ).isTrue(); + + Class packageLike = loadForMapper( PackageAbstractionMapper.class ); + assertThat( isDefault( packageLike.getModifiers() ) ).isTrue(); + + Class forcedPublic = loadForMapper( ForcedPublicMapper.class ); + assertThat( isPublic( forcedPublic.getModifiers() ) ).isTrue(); + + Class forcedDefault = loadForMapper( ForcedPackagePrivateMapper.class ); + assertThat( isDefault( forcedDefault.getModifiers() ) ).isTrue(); + } + + private static Class loadForMapper(Class mapper) throws ClassNotFoundException { + return Thread.currentThread().getContextClassLoader().loadClass( mapper.getName() + "Impl" ); + } + + private static boolean isDefault(int modifiers) { + return !isPublic( modifiers ) && !isProtected( modifiers ) && !isPrivate( modifiers ); + } +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ForcedPackagePrivateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ForcedPackagePrivateMapper.java new file mode 100644 index 0000000000..191aadb2a0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ForcedPackagePrivateMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +import org.mapstruct.ClassAccessibility; +import org.mapstruct.Mapper; + +@Mapper(accessibility = ClassAccessibility.PACKAGE_PRIVATE) +public interface ForcedPackagePrivateMapper { + Target map(Source value); +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ForcedPublicMapper.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ForcedPublicMapper.java new file mode 100644 index 0000000000..fd6ced910a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/ForcedPublicMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +import org.mapstruct.ClassAccessibility; +import org.mapstruct.Mapper; + +@Mapper(accessibility = ClassAccessibility.PUBLIC) +interface ForcedPublicMapper { + Target map(Source value); +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/PackageAbstractionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/PackageAbstractionMapper.java new file mode 100644 index 0000000000..d9f426b382 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/PackageAbstractionMapper.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +import org.mapstruct.Mapper; + +@Mapper +interface PackageAbstractionMapper { + Target map(Source value); +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/PublicAbstractionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/PublicAbstractionMapper.java new file mode 100644 index 0000000000..7c1b5de10f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/PublicAbstractionMapper.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +import org.mapstruct.Mapper; + +@Mapper +public interface PublicAbstractionMapper { + Target map(Source value); +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/Source.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/Source.java new file mode 100644 index 0000000000..feff965719 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/Source.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +/** + * @author Raimund Klein + **/ +public class Source { + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/Target.java b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/Target.java new file mode 100644 index 0000000000..e8c50a2531 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/classaccessibility/Target.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.classaccessibility; + +/** + * @author Raimund Klein + **/ +public class Target { + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java index 8dfa001b4a..42ef2a25a3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/CollectionMappingTest.java @@ -1,26 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; @@ -30,20 +14,20 @@ import java.util.Map; import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; @WithClasses({ Source.class, Target.class, Colour.class, SourceTargetMapper.class, TestList.class, TestMap.class, StringHolderArrayList.class, StringHolderToLongMap.class, StringHolder.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class CollectionMappingTest { - @Test + @ProcessorTest @IssueKey("6") public void shouldMapNullList() { Source source = new Source(); @@ -54,7 +38,7 @@ public void shouldMapNullList() { assertThat( target.getStringList() ).isNull(); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapNullList() { Target target = new Target(); @@ -65,7 +49,7 @@ public void shouldReverseMapNullList() { assertThat( source.getStringList() ).isNull(); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapList() { Source source = new Source(); @@ -77,7 +61,7 @@ public void shouldMapList() { assertThat( target.getStringList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("92") public void shouldMapListWithoutSetter() { Source source = new Source(); @@ -89,7 +73,7 @@ public void shouldMapListWithoutSetter() { assertThat( target.getStringListNoSetter() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapList() { Target target = new Target(); @@ -101,7 +85,7 @@ public void shouldReverseMapList() { assertThat( source.getStringList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapListAsCopy() { Source source = new Source(); @@ -114,7 +98,7 @@ public void shouldMapListAsCopy() { assertThat( source.getStringList() ).isNotEqualTo( target.getStringList() ); } - @Test + @ProcessorTest @IssueKey( "153" ) public void shouldMapListWithClearAndAddAll() { Source source = new Source(); @@ -126,7 +110,7 @@ public void shouldMapListWithClearAndAddAll() { assertThat( source.getOtherStringList() ).containsExactly( "Bob", "Alice" ); // prepare a test list to monitor add all behaviour - List testList = new TestList(); + List testList = new TestList<>(); testList.addAll( target.getOtherStringList() ); TestList.setAddAllCalled( false ); target.setOtherStringList( testList ); @@ -143,7 +127,7 @@ public void shouldMapListWithClearAndAddAll() { TestList.setAddAllCalled( false ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapListAsCopy() { Target target = new Target(); @@ -155,11 +139,11 @@ public void shouldReverseMapListAsCopy() { assertThat( target.getStringList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapArrayList() { Source source = new Source(); - source.setStringArrayList( new ArrayList( Arrays.asList( "Bob", "Alice" ) ) ); + source.setStringArrayList( new ArrayList<>( Arrays.asList( "Bob", "Alice" ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -167,11 +151,11 @@ public void shouldMapArrayList() { assertThat( target.getStringArrayList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapArrayList() { Target target = new Target(); - target.setStringArrayList( new ArrayList( Arrays.asList( "Bob", "Alice" ) ) ); + target.setStringArrayList( new ArrayList<>( Arrays.asList( "Bob", "Alice" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -179,11 +163,11 @@ public void shouldReverseMapArrayList() { assertThat( source.getStringArrayList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapSet() { Source source = new Source(); - source.setStringSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + source.setStringSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -191,11 +175,11 @@ public void shouldMapSet() { assertThat( target.getStringSet() ).contains( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapSet() { Target target = new Target(); - target.setStringSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + target.setStringSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -203,11 +187,11 @@ public void shouldReverseMapSet() { assertThat( source.getStringSet() ).contains( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapSetAsCopy() { Source source = new Source(); - source.setStringSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + source.setStringSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); target.getStringSet().add( "Bill" ); @@ -215,11 +199,11 @@ public void shouldMapSetAsCopy() { assertThat( source.getStringSet() ).containsOnly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapHashSetAsCopy() { Source source = new Source(); - source.setStringHashSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + source.setStringHashSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); target.getStringHashSet().add( "Bill" ); @@ -227,11 +211,11 @@ public void shouldMapHashSetAsCopy() { assertThat( source.getStringHashSet() ).containsOnly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapSetAsCopy() { Target target = new Target(); - target.setStringSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + target.setStringSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); source.getStringSet().add( "Bill" ); @@ -239,7 +223,7 @@ public void shouldReverseMapSetAsCopy() { assertThat( target.getStringSet() ).containsOnly( "Bob", "Alice" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapListToCollection() { Source source = new Source(); @@ -251,7 +235,7 @@ public void shouldMapListToCollection() { assertThat( target.getIntegerCollection() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapListToCollection() { Target target = new Target(); @@ -263,11 +247,11 @@ public void shouldReverseMapListToCollection() { assertThat( source.getIntegerList() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapIntegerSetToRawSet() { Source source = new Source(); - source.setIntegerSet( new HashSet( Arrays.asList( 1, 2 ) ) ); + source.setIntegerSet( new HashSet<>( Arrays.asList( 1, 2 ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -275,11 +259,11 @@ public void shouldMapIntegerSetToRawSet() { assertThat( target.getSet() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapIntegerSetToStringSet() { Source source = new Source(); - source.setAnotherIntegerSet( new HashSet( Arrays.asList( 1, 2 ) ) ); + source.setAnotherIntegerSet( new HashSet<>( Arrays.asList( 1, 2 ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -287,11 +271,11 @@ public void shouldMapIntegerSetToStringSet() { assertThat( target.getAnotherStringSet() ).containsOnly( "1", "2" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapIntegerSetToStringSet() { Target target = new Target(); - target.setAnotherStringSet( new HashSet( Arrays.asList( "1", "2" ) ) ); + target.setAnotherStringSet( new HashSet<>( Arrays.asList( "1", "2" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -299,7 +283,7 @@ public void shouldReverseMapIntegerSetToStringSet() { assertThat( source.getAnotherIntegerSet() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldMapSetOfEnumToStringSet() { Source source = new Source(); @@ -311,11 +295,11 @@ public void shouldMapSetOfEnumToStringSet() { assertThat( target.getColours() ).containsOnly( "BLUE", "GREEN" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapSetOfEnumToStringSet() { Target target = new Target(); - target.setColours( new HashSet( Arrays.asList( "BLUE", "GREEN" ) ) ); + target.setColours( new HashSet<>( Arrays.asList( "BLUE", "GREEN" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -323,11 +307,11 @@ public void shouldReverseMapSetOfEnumToStringSet() { assertThat( source.getColours() ).containsOnly( Colour.GREEN, Colour.BLUE ); } - @Test + @ProcessorTest public void shouldMapMapAsCopy() { Source source = new Source(); - Map map = new HashMap(); + Map map = new HashMap<>(); map.put( "Bob", 123L ); map.put( "Alice", 456L ); source.setStringLongMap( map ); @@ -339,12 +323,12 @@ public void shouldMapMapAsCopy() { assertThat( target.getStringLongMap() ).hasSize( 3 ); } - @Test + @ProcessorTest @IssueKey( "153" ) public void shouldMapMapWithClearAndPutAll() { Source source = new Source(); - Map map = new HashMap(); + Map map = new HashMap<>(); map.put( "Bob", 123L ); map.put( "Alice", 456L ); source.setOtherStringLongMap( map ); @@ -358,7 +342,7 @@ public void shouldMapMapWithClearAndPutAll() { source.getOtherStringLongMap().remove( "Alice" ); // prepare a test list to monitor add all behaviour - Map originalInstance = new TestMap(); + Map originalInstance = new TestMap<>(); originalInstance.putAll( target.getOtherStringLongMap() ); TestMap.setPuttAllCalled( false ); target.setOtherStringLongMap( originalInstance ); @@ -371,17 +355,17 @@ public void shouldMapMapWithClearAndPutAll() { TestMap.setPuttAllCalled( false ); } - @Test + @ProcessorTest @IssueKey("87") public void shouldMapIntegerSetToNumberSet() { Set numbers = SourceTargetMapper.INSTANCE - .integerSetToNumberSet( new HashSet( Arrays.asList( 123, 456 ) ) ); + .integerSetToNumberSet( new HashSet<>( Arrays.asList( 123, 456 ) ) ); assertThat( numbers ).isNotNull(); assertThat( numbers ).containsOnly( 123, 456 ); } - @Test + @ProcessorTest @IssueKey("732") public void shouldEnumSetAsCopy() { Source source = new Source(); @@ -394,11 +378,11 @@ public void shouldEnumSetAsCopy() { assertThat( target.getEnumSet() ).containsOnly( Colour.BLUE, Colour.GREEN ); } - @Test + @ProcessorTest @IssueKey("853") public void shouldMapNonGenericList() { Source source = new Source(); - source.setStringList3( new ArrayList( Arrays.asList( "Bob", "Alice" ) ) ); + source.setStringList3( new ArrayList<>( Arrays.asList( "Bob", "Alice" ) ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -419,12 +403,11 @@ public void shouldMapNonGenericList() { assertThat( mappedSource.getStringList3() ).containsExactly( "Bill", "Bob" ); } - @SuppressWarnings("unchecked") - @Test + @ProcessorTest @IssueKey("853") public void shouldMapNonGenericMap() { Source source = new Source(); - Map map = new HashMap(); + Map map = new HashMap<>(); map.put( "Bob", 123L ); map.put( "Alice", 456L ); source.setStringLongMapForNonGeneric( map ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/Colour.java b/processor/src/test/java/org/mapstruct/ap/test/collection/Colour.java index 15da46b18c..b9cb1870f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/Colour.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/Colour.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java index d00ed3e986..0ceb45af7d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java index fd192d07bf..1782ebdb57 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; @@ -34,13 +21,13 @@ public abstract class SourceTargetMapper { static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mappings({ - @Mapping(source = "integerList", target = "integerCollection"), - @Mapping(source = "integerSet", target = "set"), - @Mapping(source = "anotherIntegerSet", target = "anotherStringSet"), - @Mapping(source = "stringList2", target = "stringListNoSetter"), - @Mapping(source = "stringSet2", target = "stringListNoSetter2"), - @Mapping(source = "stringList3", target = "nonGenericStringList"), - @Mapping(source = "stringLongMapForNonGeneric", target = "nonGenericMapStringtoLong") + @Mapping(target = "integerCollection", source = "integerList"), + @Mapping(target = "set", source = "integerSet"), + @Mapping(target = "anotherStringSet", source = "anotherIntegerSet"), + @Mapping(target = "stringListNoSetter", source = "stringList2"), + @Mapping(target = "stringListNoSetter2", source = "stringSet2"), + @Mapping(target = "nonGenericStringList", source = "stringList3"), + @Mapping(target = "nonGenericMapStringtoLong", source = "stringLongMapForNonGeneric") }) public abstract Target sourceToTarget(Source source); @@ -50,8 +37,6 @@ public abstract class SourceTargetMapper { @InheritConfiguration public abstract Target sourceToTargetTwoArg(Source source, @MappingTarget Target target); - public abstract Set integerSetToStringSet(Set integers); - @InheritInverseConfiguration public abstract Set stringSetToIntegerSet(Set strings); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolder.java b/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolder.java index 5e1f823c10..af3539ff9e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolder.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolder.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; @@ -54,13 +41,10 @@ public boolean equals(Object obj) { } StringHolder other = (StringHolder) obj; if ( string == null ) { - if ( other.string != null ) { - return false; - } + return other.string == null; } - else if ( !string.equals( other.string ) ) { - return false; + else { + return string.equals( other.string ); } - return true; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderArrayList.java b/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderArrayList.java index 56de9408e3..6b3b4fd4b6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderArrayList.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderArrayList.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderToLongMap.java b/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderToLongMap.java index 2334e4feba..9705f2b12f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderToLongMap.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/StringHolderToLongMap.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java index 3b16a91b3d..2ff6cbfb2c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/Target.java @@ -1,34 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - public class Target { //CHECKSTYLE:OFF @@ -67,10 +52,11 @@ public class Target { private StringHolderToLongMap nonGenericMapStringtoLong; public Target() { - otherStringLongMap = Maps.newHashMap(); + otherStringLongMap = new HashMap<>(); otherStringLongMap.put( "not-present-after-mapping", 42L ); - otherStringList = Lists.newArrayList( "not-present-after-mapping" ); + otherStringList = new ArrayList<>(); + otherStringList.add( "not-present-after-mapping" ); } public List getStringList() { @@ -157,14 +143,14 @@ public void setStringLongMap(Map stringLongMap) { public List getStringListNoSetter() { if ( stringListNoSetter == null ) { - stringListNoSetter = new ArrayList(); + stringListNoSetter = new ArrayList<>(); } return stringListNoSetter; } public List getStringListNoSetter2() { if ( stringListNoSetter2 == null ) { - stringListNoSetter2 = new ArrayList(); + stringListNoSetter2 = new ArrayList<>(); } return stringListNoSetter2; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/TestList.java b/processor/src/test/java/org/mapstruct/ap/test/collection/TestList.java index b06da0d389..68741e5b84 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/TestList.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/TestList.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/TestMap.java b/processor/src/test/java/org/mapstruct/ap/test/collection/TestMap.java index a9d3c74aee..6ff922fc1e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/TestMap.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/TestMap.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/AdderTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/AdderTest.java index 6f434d2db6..b555970770 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/AdderTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/AdderTest.java @@ -1,33 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.util.ArrayList; import java.util.Arrays; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.collection.adder._target.AdderUsageObserver; import org.mapstruct.ap.test.collection.adder._target.IndoorPet; import org.mapstruct.ap.test.collection.adder._target.OutdoorPet; @@ -38,32 +19,42 @@ import org.mapstruct.ap.test.collection.adder._target.TargetHuman; import org.mapstruct.ap.test.collection.adder._target.TargetOnlyGetter; import org.mapstruct.ap.test.collection.adder._target.TargetViaTargetType; +import org.mapstruct.ap.test.collection.adder._target.TargetWithAnimals; import org.mapstruct.ap.test.collection.adder._target.TargetWithoutSetter; import org.mapstruct.ap.test.collection.adder.source.Foo; import org.mapstruct.ap.test.collection.adder.source.SingleElementSource; import org.mapstruct.ap.test.collection.adder.source.Source; import org.mapstruct.ap.test.collection.adder.source.Source2; import org.mapstruct.ap.test.collection.adder.source.SourceTeeth; +import org.mapstruct.ap.test.collection.adder.source.SourceWithPets; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + /** * @author Sjaak Derksen */ @WithClasses({ Source.class, SourceTeeth.class, + SourceWithPets.class, Target.class, TargetDali.class, TargetHuman.class, TargetOnlyGetter.class, TargetViaTargetType.class, TargetWithoutSetter.class, + TargetWithAnimals.class, SourceTargetMapper.class, SourceTargetMapperStrategyDefault.class, SourceTargetMapperStrategySetterPreferred.class, + SourceTargetMapperWithDifferentProperties.class, SingleElementSource.class, PetMapper.class, TeethMapper.class, @@ -78,18 +69,17 @@ Source2Target2Mapper.class, Foo.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class AdderTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( SourceTargetMapper.class, SourceTargetMapperStrategyDefault.class, SourceTargetMapperStrategySetterPreferred.class ); @IssueKey("241") - @Test + @ProcessorTest public void testAdd() throws DogException { AdderUsageObserver.setUsed( false ); @@ -103,36 +93,38 @@ public void testAdd() throws DogException { assertTrue( AdderUsageObserver.isUsed() ); } - @Test(expected = DogException.class) + @ProcessorTest public void testAddWithExceptionInThrowsClause() throws DogException { AdderUsageObserver.setUsed( false ); Source source = new Source(); source.setPets( Arrays.asList( "dog" ) ); - SourceTargetMapper.INSTANCE.toTarget( source ); + assertThatThrownBy( () -> SourceTargetMapper.INSTANCE.toTarget( source ) ) + .isInstanceOf( DogException.class ); } - @Test(expected = RuntimeException.class) + @ProcessorTest public void testAddWithExceptionNotInThrowsClause() throws DogException { AdderUsageObserver.setUsed( false ); Source source = new Source(); source.setPets( Arrays.asList( "cat" ) ); - SourceTargetMapper.INSTANCE.toTarget( source ); + assertThatThrownBy( () -> SourceTargetMapper.INSTANCE.toTarget( source ) ) + .isInstanceOf( RuntimeException.class ); } @IssueKey("241") - @Test - public void testAddwithExistingTarget() throws DogException { + @ProcessorTest + public void testAddWithExistingTarget() { AdderUsageObserver.setUsed( false ); Source source = new Source(); source.setPets( Arrays.asList( "mouse" ) ); Target target = new Target(); - target.setPets( new ArrayList( Arrays.asList( 1L ) ) ); + target.setPets( new ArrayList<>( Arrays.asList( 1L ) ) ); SourceTargetMapper.INSTANCE.toExistingTarget( source, target ); assertThat( target ).isNotNull(); @@ -142,7 +134,7 @@ public void testAddwithExistingTarget() throws DogException { assertTrue( AdderUsageObserver.isUsed() ); } - @Test + @ProcessorTest public void testShouldUseDefaultStrategy() throws DogException { AdderUsageObserver.setUsed( false ); @@ -156,7 +148,7 @@ public void testShouldUseDefaultStrategy() throws DogException { assertFalse( AdderUsageObserver.isUsed() ); } - @Test + @ProcessorTest public void testShouldPreferSetterStrategyButThereIsNone() throws DogException { AdderUsageObserver.setUsed( false ); @@ -170,7 +162,7 @@ public void testShouldPreferSetterStrategyButThereIsNone() throws DogException { assertTrue( AdderUsageObserver.isUsed() ); } - @Test + @ProcessorTest public void testShouldPreferHumanSingular() { AdderUsageObserver.setUsed( false ); @@ -185,8 +177,8 @@ public void testShouldPreferHumanSingular() { assertTrue( AdderUsageObserver.isUsed() ); } - @Test - public void testshouldFallBackToDaliSingularInAbsenseOfHumanSingular() { + @ProcessorTest + public void testShouldFallBackToDaliSingularInAbsenceOfHumanSingular() { AdderUsageObserver.setUsed( false ); SourceTeeth source = new SourceTeeth(); @@ -199,8 +191,8 @@ public void testshouldFallBackToDaliSingularInAbsenseOfHumanSingular() { assertTrue( AdderUsageObserver.isUsed() ); } - @Test - public void testAddReverse() throws DogException { + @ProcessorTest + public void testAddReverse() { AdderUsageObserver.setUsed( false ); Target source = new Target(); @@ -212,7 +204,7 @@ public void testAddReverse() throws DogException { assertThat( target.getPets().get( 0 ) ).isEqualTo( "cat" ); } - @Test + @ProcessorTest public void testAddOnlyGetter() throws DogException { AdderUsageObserver.setUsed( false ); @@ -226,8 +218,8 @@ public void testAddOnlyGetter() throws DogException { assertTrue( AdderUsageObserver.isUsed() ); } - @Test - public void testAddViaTargetType() throws DogException { + @ProcessorTest + public void testAddViaTargetType() { AdderUsageObserver.setUsed( false ); Source source = new Source(); @@ -242,8 +234,8 @@ public void testAddViaTargetType() throws DogException { } @IssueKey("242") - @Test - public void testSingleElementSource() throws DogException { + @ProcessorTest + public void testSingleElementSource() { AdderUsageObserver.setUsed( false ); SingleElementSource source = new SingleElementSource(); @@ -257,8 +249,8 @@ public void testSingleElementSource() throws DogException { } @IssueKey( "310" ) - @Test - public void testMissingImport() throws DogException { + @ProcessorTest + public void testMissingImport() { generatedSource.addComparisonToFixtureFor( Source2Target2Mapper.class ); Source2 source = new Source2(); @@ -268,4 +260,17 @@ public void testMissingImport() throws DogException { assertThat( target ).isNotNull(); assertThat( target.getAttributes().size() ).isEqualTo( 1 ); } + + @IssueKey("1478") + @ProcessorTest + public void useIterationNameFromSource() { + generatedSource.addComparisonToFixtureFor( SourceTargetMapperWithDifferentProperties.class ); + + SourceWithPets source = new SourceWithPets(); + source.setPets( Arrays.asList( "dog", "cat" ) ); + + TargetWithAnimals target = SourceTargetMapperWithDifferentProperties.INSTANCE.map( source ); + + assertThat( target.getAnimals() ).containsExactly( "dog", "cat" ); + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/CatException.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/CatException.java index 26e8dc605f..970f7d7368 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/CatException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/CatException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/DogException.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/DogException.java index 3e91e3d020..e28c2749c5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/DogException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/DogException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/PetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/PetMapper.java index 837a4baad1..601b62c6b6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/PetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/PetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; @@ -22,13 +9,12 @@ import java.util.List; import java.util.Map; +import com.google.common.collect.ImmutableMap; import org.mapstruct.TargetType; import org.mapstruct.ap.test.collection.adder._target.IndoorPet; import org.mapstruct.ap.test.collection.adder._target.OutdoorPet; import org.mapstruct.ap.test.collection.adder._target.Pet; -import com.google.common.collect.ImmutableMap; - /** * @author Sjaak Derksen */ @@ -44,7 +30,6 @@ public class PetMapper { .put( 3L, "cat" ) .put( 4L, "dog" ).build(); - /** * method to be used when using an adder * @@ -76,7 +61,7 @@ else if ( "dog".equals( pet ) ) { * @throws DogException */ public List toPets(List pets) throws CatException, DogException { - List result = new ArrayList(); + List result = new ArrayList<>(); for ( String pet : pets ) { result.add( toPet( pet ) ); } @@ -95,7 +80,7 @@ public T toPet(String pet, @TargetType Class clazz) throws Ca } public List toSourcePets(List pets) throws CatException, DogException { - List result = new ArrayList(); + List result = new ArrayList<>(); for ( Long pet : pets ) { result.add( PETS_TO_SOURCE.get( pet ) ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/Source2Target2Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/Source2Target2Mapper.java index 9b3a301119..a0be9730fe 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/Source2Target2Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/Source2Target2Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapper.java index 10b5167456..18b542e99d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; @@ -55,6 +42,6 @@ public interface SourceTargetMapper { TargetViaTargetType toTargetViaTargetType(Source source); - @Mapping(source = "pet", target = "pets") + @Mapping(target = "pets", source = "pet") Target fromSingleElementSource(SingleElementSource source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategyDefault.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategyDefault.java index 08670928f6..4a824fa768 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategyDefault.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategyDefault.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategySetterPreferred.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategySetterPreferred.java index 97b0551d0a..93a5a7e531 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategySetterPreferred.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperStrategySetterPreferred.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperWithDifferentProperties.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperWithDifferentProperties.java new file mode 100644 index 0000000000..b0460c2650 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/SourceTargetMapperWithDifferentProperties.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.adder; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.collection.adder._target.TargetWithAnimals; +import org.mapstruct.ap.test.collection.adder.source.SourceWithPets; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED) +public interface SourceTargetMapperWithDifferentProperties { + + SourceTargetMapperWithDifferentProperties INSTANCE = + Mappers.getMapper( SourceTargetMapperWithDifferentProperties.class ); + + @Mapping(target = "animals", source = "pets") + TargetWithAnimals map(SourceWithPets source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/TeethMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/TeethMapper.java index 89d36d03cd..06e416828b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/TeethMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/TeethMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/AdderUsageObserver.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/AdderUsageObserver.java index 71c15d6325..c579b8e40a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/AdderUsageObserver.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/AdderUsageObserver.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/IndoorPet.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/IndoorPet.java index 17c077c12e..954ced0938 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/IndoorPet.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/IndoorPet.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/OutdoorPet.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/OutdoorPet.java index 296f540489..8cb2475e6e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/OutdoorPet.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/OutdoorPet.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Pet.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Pet.java index 8920b71dcf..145f2b85ad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Pet.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Pet.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target.java index 7d87d1b7ec..b131bd96ea 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -37,21 +24,21 @@ public void setPets(List pets) { } public void addCat(Long cat) { - // dummy method to test selection mechanims + // dummy method to test selection mechanism } public void addDog(Long cat) { - // dummy method to test selection mechanims + // dummy method to test selection mechanism } public void addPets(Long cat) { - // dummy method to test selection mechanims + // dummy method to test selection mechanism } public Long addPet(Long pet) { AdderUsageObserver.setUsed( true ); if ( pets == null ) { - pets = new ArrayList(); + pets = new ArrayList<>(); } pets.add( pet ); return pet; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target2.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target2.java index 946e7f4982..bd6e8f9979 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/Target2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -29,7 +16,7 @@ */ public class Target2 { - private List attributes = new ArrayList(); + private List attributes = new ArrayList<>(); public Foo addAttribute( Foo foo ) { attributes.add( foo ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetDali.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetDali.java index 5f45e150f4..30f11f3807 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetDali.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetDali.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -39,7 +26,7 @@ public void setTeeth(List teeth) { public void addTeeth(Integer tooth) { AdderUsageObserver.setUsed( true ); if ( teeth == null ) { - teeth = new ArrayList(); + teeth = new ArrayList<>(); } teeth.add( tooth ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetHuman.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetHuman.java index f2ff11f0f0..3a2efb9b81 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetHuman.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetHuman.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -39,14 +26,14 @@ public void setTeeth(List teeth) { public void addTooth(Integer pet) { AdderUsageObserver.setUsed( true ); if ( teeth == null ) { - teeth = new ArrayList(); + teeth = new ArrayList<>(); } teeth.add( pet ); } public void addTeeth(Integer tooth) { if ( teeth == null ) { - teeth = new ArrayList(); + teeth = new ArrayList<>(); } teeth.add( tooth ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetOnlyGetter.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetOnlyGetter.java index 5a8dc634c4..d9d593a230 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetOnlyGetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetOnlyGetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -33,21 +20,21 @@ public List getPets() { } public void addCat(Long cat) { - // dummy method to test selection mechanims + // dummy method to test selection mechanism } public void addDog(Long cat) { - // dummy method to test selection mechanims + // dummy method to test selection mechanism } public void addPets(Long cat) { - // dummy method to test selection mechanims + // dummy method to test selection mechanism } public void addPet(Long pet) { AdderUsageObserver.setUsed( true ); if ( pets == null ) { - pets = new ArrayList(); + pets = new ArrayList<>(); } pets.add( pet ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetViaTargetType.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetViaTargetType.java index ec5fabad8b..22123aa970 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetViaTargetType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetViaTargetType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -39,7 +26,7 @@ public void setPets(List pets) { public void addPet(IndoorPet pet) { AdderUsageObserver.setUsed( true ); if ( pets == null ) { - pets = new ArrayList(); + pets = new ArrayList<>(); } pets.add( pet ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithAnimals.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithAnimals.java new file mode 100644 index 0000000000..10770922bd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithAnimals.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.adder._target; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class TargetWithAnimals { + + private List animals = new ArrayList<>(); + + public List getAnimals() { + return animals; + } + + public void setAnimals(List animals) { + this.animals = animals; + } + + public void addAnimal(String animal) { + animals.add( animal ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithoutSetter.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithoutSetter.java index 695765c0bf..61e670c3a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithoutSetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/_target/TargetWithoutSetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder._target; @@ -35,7 +22,7 @@ public List getPets() { public void addPet(Long pet) { AdderUsageObserver.setUsed( true ); if ( pets == null ) { - pets = new ArrayList(); + pets = new ArrayList<>(); } pets.add( pet ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Foo.java index 00be6cfbe0..6395243177 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SingleElementSource.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SingleElementSource.java index a9cf9f5fd0..01ab35a91d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SingleElementSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SingleElementSource.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder.source; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source.java index c70f549b1e..862ea96fc3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source2.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source2.java index 356d8ea38e..93369bde2d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/Source2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceTeeth.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceTeeth.java index e5d02df58f..3abe3afc2e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceTeeth.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceTeeth.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.adder.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceWithPets.java b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceWithPets.java new file mode 100644 index 0000000000..bbb0006532 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/adder/source/SourceWithPets.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.adder.source; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class SourceWithPets { + + private List pets; + + public List getPets() { + return pets; + } + + public void setPets(List pets) { + this.pets = pets; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/DefaultCollectionImplementationTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/DefaultCollectionImplementationTest.java index ce6a0a245c..dccfcf01ca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/DefaultCollectionImplementationTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/DefaultCollectionImplementationTest.java @@ -1,26 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -36,14 +20,15 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentNavigableMap; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + @WithClasses({ Source.class, Target.class, @@ -51,14 +36,13 @@ TargetFoo.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class DefaultCollectionImplementationTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource() + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() .addComparisonToFixtureFor( SourceTargetMapper.class ); - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForConcurrentMap() { ConcurrentMap target = @@ -67,7 +51,7 @@ public void shouldUseDefaultImplementationForConcurrentMap() { assertResultMap( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForConcurrentNavigableMap() { ConcurrentNavigableMap target = @@ -76,7 +60,7 @@ public void shouldUseDefaultImplementationForConcurrentNavigableMap() { assertResultMap( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForMap() { Map target = SourceTargetMapper.INSTANCE.sourceFooMapToTargetFooMap( createSourceFooMap() ); @@ -84,7 +68,7 @@ public void shouldUseDefaultImplementationForMap() { assertResultMap( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForNavigableMap() { NavigableMap target = @@ -93,7 +77,7 @@ public void shouldUseDefaultImplementationForNavigableMap() { assertResultMap( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForSortedMap() { SortedMap target = @@ -102,7 +86,7 @@ public void shouldUseDefaultImplementationForSortedMap() { assertResultMap( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForNaviableSet() { NavigableSet target = @@ -111,7 +95,7 @@ public void shouldUseDefaultImplementationForNaviableSet() { assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForCollection() { Collection target = @@ -120,7 +104,7 @@ public void shouldUseDefaultImplementationForCollection() { assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForIterable() { Iterable target = @@ -129,7 +113,7 @@ public void shouldUseDefaultImplementationForIterable() { assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForList() { List target = SourceTargetMapper.INSTANCE.sourceFoosToTargetFoos( createSourceFooList() ); @@ -137,16 +121,16 @@ public void shouldUseDefaultImplementationForList() { assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForSet() { Set target = - SourceTargetMapper.INSTANCE.sourceFoosToTargetFoos( new HashSet( createSourceFooList() ) ); + SourceTargetMapper.INSTANCE.sourceFoosToTargetFoos( new HashSet<>( createSourceFooList() ) ); assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldUseDefaultImplementationForSortedSet() { SortedSet target = @@ -155,10 +139,10 @@ public void shouldUseDefaultImplementationForSortedSet() { assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("19") public void shouldUseTargetParameterForMapping() { - List target = new ArrayList(); + List target = new ArrayList<>(); SourceTargetMapper.INSTANCE.sourceFoosToTargetFoosUsingTargetParameter( target, createSourceFooList() @@ -167,19 +151,33 @@ public void shouldUseTargetParameterForMapping() { assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("19") public void shouldUseAndReturnTargetParameterForMapping() { - List target = new ArrayList(); + List target = new ArrayList<>(); Iterable result = SourceTargetMapper.INSTANCE .sourceFoosToTargetFoosUsingTargetParameterAndReturn( createSourceFooList(), target ); - assertThat( target == result ).isTrue(); + assertThat( result ).isSameAs( target ); + assertResultList( target ); + } + + @ProcessorTest + @IssueKey("1752") + public void shouldUseAndReturnTargetParameterForNullMapping() { + List target = new ArrayList<>(); + target.add( new TargetFoo( "Bob" ) ); + target.add( new TargetFoo( "Alice" ) ); + Iterable result = + SourceTargetMapper.INSTANCE + .sourceFoosToTargetFoosUsingTargetParameterAndReturn( null, target ); + + assertThat( result ).isSameAs( target ); assertResultList( target ); } - @Test + @ProcessorTest @IssueKey("92") public void shouldUseDefaultImplementationForListWithoutSetter() { Source source = new Source(); @@ -202,7 +200,7 @@ private void assertResultMap(Map result) { } private Map createSourceFooMap() { - Map map = new HashMap(); + Map map = new HashMap<>(); map.put( 1L, new SourceFoo( "Bob" ) ); map.put( 2L, new SourceFoo( "Alice" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterCollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterCollectionMappingTest.java index 5326ccbd6c..8723969723 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterCollectionMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterCollectionMappingTest.java @@ -1,51 +1,35 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; /** * @author Andreas Gudian * */ @WithClasses( { NoSetterMapper.class, NoSetterSource.class, NoSetterTarget.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class NoSetterCollectionMappingTest { - @Test + @ProcessorTest @IssueKey( "220" ) public void compilesAndMapsCorrectly() { NoSetterSource source = new NoSetterSource(); source.setListValues( Arrays.asList( "foo", "bar" ) ); - HashMap mapValues = new HashMap(); + HashMap mapValues = new HashMap<>(); mapValues.put( "fooKey", "fooVal" ); mapValues.put( "barKey", "barVal" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterMapper.java index 58eb9db200..0c7302d657 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterSource.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterSource.java index f17d6f5efd..6bb1d429b4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterTarget.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterTarget.java index c266f7f413..817879fa01 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/NoSetterTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; @@ -28,8 +15,8 @@ * */ public class NoSetterTarget { - private List listValues = new ArrayList(); - private Map mapValues = new HashMap(); + private List listValues = new ArrayList<>(); + private Map mapValues = new HashMap<>(); public List getListValues() { return listValues; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Source.java index 96236406f5..990681492a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceFoo.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceFoo.java index e2d7671b47..697c27fe45 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceFoo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceFoo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceTargetMapper.java index 724c9f647f..2f0d8085e8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; @@ -39,7 +26,7 @@ public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - @Mapping(source = "fooList", target = "fooListNoSetter") + @Mapping(target = "fooListNoSetter", source = "fooList") Target sourceToTarget(Source source); TargetFoo sourceFooToTargetFoo(SourceFoo sourceFoo); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Target.java index 1293637a30..713865da62 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; @@ -27,7 +14,7 @@ public class Target { public List getFooListNoSetter() { if ( fooListNoSetter == null ) { - fooListNoSetter = new ArrayList(); + fooListNoSetter = new ArrayList<>(); } return fooListNoSetter; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/TargetFoo.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/TargetFoo.java index 9b2b909200..5a843b045c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/TargetFoo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/TargetFoo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.defaultimplementation; @@ -58,14 +45,11 @@ public boolean equals(Object obj) { } TargetFoo other = (TargetFoo) obj; if ( name == null ) { - if ( other.name != null ) { - return false; - } + return other.name == null; } - else if ( !name.equals( other.name ) ) { - return false; + else { + return name.equals( other.name ); } - return true; } @Override diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/jdk21/SequencedCollectionsDefaultImplementationTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/jdk21/SequencedCollectionsDefaultImplementationTest.java new file mode 100644 index 0000000000..4551d5b0b3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/jdk21/SequencedCollectionsDefaultImplementationTest.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.defaultimplementation.jdk21; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.SequencedMap; +import java.util.SequencedSet; + +import org.mapstruct.ap.test.collection.defaultimplementation.Source; +import org.mapstruct.ap.test.collection.defaultimplementation.SourceFoo; +import org.mapstruct.ap.test.collection.defaultimplementation.Target; +import org.mapstruct.ap.test.collection.defaultimplementation.TargetFoo; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; + +@WithClasses({ + Source.class, + Target.class, + SourceFoo.class, + TargetFoo.class, + SequencedCollectionsMapper.class +}) +@IssueKey("3420") +class SequencedCollectionsDefaultImplementationTest { + + @ProcessorTest + public void shouldUseDefaultImplementationForSequencedMap() { + SequencedMap target = + SequencedCollectionsMapper.INSTANCE.sourceFooMapToTargetFooSequencedMap( createSourceFooMap() ); + + assertResultMap( target ); + } + + @ProcessorTest + public void shouldUseDefaultImplementationForSequencedSet() { + SequencedSet target = + SequencedCollectionsMapper.INSTANCE.sourceFoosToTargetFooSequencedSet( createSourceFooList() ); + + assertResultList( target ); + } + + private void assertResultList(Iterable fooIterable) { + assertThat( fooIterable ).isNotNull(); + assertThat( fooIterable ).containsOnly( new TargetFoo( "Bob" ), new TargetFoo( "Alice" ) ); + } + + private void assertResultMap(Map result) { + assertThat( result ).isNotNull(); + assertThat( result ).hasSize( 2 ); + assertThat( result ).contains( entry( "1", new TargetFoo( "Bob" ) ), entry( "2", new TargetFoo( "Alice" ) ) ); + } + + private Map createSourceFooMap() { + Map map = new HashMap<>(); + map.put( 1L, new SourceFoo( "Bob" ) ); + map.put( 2L, new SourceFoo( "Alice" ) ); + + return map; + } + + private List createSourceFooList() { + return Arrays.asList( new SourceFoo( "Bob" ), new SourceFoo( "Alice" ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/jdk21/SequencedCollectionsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/jdk21/SequencedCollectionsMapper.java new file mode 100644 index 0000000000..bbffb56b0c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/defaultimplementation/jdk21/SequencedCollectionsMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.defaultimplementation.jdk21; + +import java.util.Collection; +import java.util.Map; +import java.util.SequencedMap; +import java.util.SequencedSet; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.collection.defaultimplementation.SourceFoo; +import org.mapstruct.ap.test.collection.defaultimplementation.TargetFoo; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SequencedCollectionsMapper { + + SequencedCollectionsMapper INSTANCE = Mappers.getMapper( SequencedCollectionsMapper.class ); + + SequencedSet sourceFoosToTargetFooSequencedSet(Collection foos); + + SequencedMap sourceFooMapToTargetFooSequencedMap(Map foos); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyItererableMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyItererableMappingMapper.java index 94513ebe9b..cc93860cbd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyItererableMappingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyItererableMappingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyMapMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyMapMappingMapper.java index 62e5a949d4..14ba978fcc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyMapMappingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/EmptyMapMappingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionMappingTest.java index 5f76775943..d9861be87e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionMappingTest.java @@ -1,64 +1,52 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.NoProperties; import org.mapstruct.ap.test.WithProperties; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Test for illegal mappings between collection types, iterable and non-iterable types etc. * * @author Gunnar Morling */ -@RunWith(AnnotationProcessorTestRunner.class) public class ErroneousCollectionMappingTest { - @Test + @ProcessorTest @IssueKey("6") - @WithClasses({ ErroneousCollectionToNonCollectionMapper.class }) + @WithClasses({ ErroneousCollectionToNonCollectionMapper.class, Source.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousCollectionToNonCollectionMapper.class, kind = Kind.ERROR, - line = 28, - messageRegExp = "Can't generate mapping method from iterable type to non-iterable type"), + line = 15, + message = "Can't generate mapping method from iterable type from java stdlib to non-iterable type."), + @Diagnostic(type = ErroneousCollectionToNonCollectionMapper.class, + kind = Kind.ERROR, + line = 17, + message = "Can't generate mapping method from non-iterable type to iterable type from java stdlib."), @Diagnostic(type = ErroneousCollectionToNonCollectionMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "Can't generate mapping method from non-iterable type to iterable type") + line = 19, + message = "Can't generate mapping method from non-iterable type to iterable type from java stdlib.") } ) - public void shouldFailToGenerateImplementationBetweenCollectionAndNonCollection() { + public void shouldFailToGenerateImplementationBetweenCollectionAndNonCollectionWithResultTypeFromJava() { } - @Test + @ProcessorTest @IssueKey("729") @WithClasses({ ErroneousCollectionToPrimitivePropertyMapper.class, Source.class, Target.class }) @ExpectedCompilationOutcome( @@ -66,16 +54,15 @@ public void shouldFailToGenerateImplementationBetweenCollectionAndNonCollection( diagnostics = { @Diagnostic(type = ErroneousCollectionToPrimitivePropertyMapper.class, kind = Kind.ERROR, - line = 26, - messageRegExp = "Can't map property \"java.util.List strings\" to \"int strings\". " - + "Consider to declare/implement a mapping method: \"int map\\(java.util.List" - + " value\\)\"") + line = 13, + message = "Can't map property \"List strings\" to \"int strings\". " + + "Consider to declare/implement a mapping method: \"int map(List value)\".") } ) public void shouldFailToGenerateImplementationBetweenCollectionAndPrimitive() { } - @Test + @ProcessorTest @IssueKey("417") @WithClasses({ EmptyItererableMappingMapper.class }) @ExpectedCompilationOutcome( @@ -83,15 +70,15 @@ public void shouldFailToGenerateImplementationBetweenCollectionAndPrimitive() { diagnostics = { @Diagnostic(type = EmptyItererableMappingMapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + line = 22, + message = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + "undefined in @IterableMapping, define at least one of them.") } ) public void shouldFailOnEmptyIterableAnnotation() { } - @Test + @ProcessorTest @IssueKey("417") @WithClasses({ EmptyMapMappingMapper.class }) @ExpectedCompilationOutcome( @@ -99,8 +86,8 @@ public void shouldFailOnEmptyIterableAnnotation() { diagnostics = { @Diagnostic(type = EmptyMapMappingMapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "'nullValueMappingStrategy', 'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', " + line = 22, + message = "'nullValueMappingStrategy', 'keyDateFormat', 'keyQualifiedBy', 'keyTargetType', " + "'valueDateFormat', 'valueQualfiedBy' and 'valueTargetType' are all undefined in @MapMapping, " + "define at least one of them.") } @@ -108,7 +95,7 @@ public void shouldFailOnEmptyIterableAnnotation() { public void shouldFailOnEmptyMapAnnotation() { } - @Test + @ProcessorTest @IssueKey("459") @WithClasses({ ErroneousCollectionNoElementMappingFound.class, NoProperties.class, WithProperties.class }) @ExpectedCompilationOutcome( @@ -116,16 +103,16 @@ public void shouldFailOnEmptyMapAnnotation() { diagnostics = { @Diagnostic(type = ErroneousCollectionNoElementMappingFound.class, kind = Kind.ERROR, - line = 38, - messageRegExp = "Can't map Collection element \".*WithProperties withProperties\" to \".*NoProperties" + - " noProperties\". Consider to declare/implement a mapping method: \".*NoProperties map\\(" + - ".*WithProperties value\\)") + line = 25, + message = "No target bean properties found: can't map Collection element " + + "\"WithProperties withProperties\" to \"NoProperties noProperties\". " + + "Consider to declare/implement a mapping method: \"NoProperties map(WithProperties value)\".") } ) public void shouldFailOnNoElementMappingFound() { } - @Test + @ProcessorTest @IssueKey("993") @WithClasses({ ErroneousCollectionNoElementMappingFoundDisabledAuto.class }) @ExpectedCompilationOutcome( @@ -133,16 +120,15 @@ public void shouldFailOnNoElementMappingFound() { diagnostics = { @Diagnostic(type = ErroneousCollectionNoElementMappingFoundDisabledAuto.class, kind = Kind.ERROR, - line = 32, - messageRegExp = - "Can't map collection element \".*AttributedString\" to \".*String \". " + - "Consider to declare/implement a mapping method: \".*String map\\(.*AttributedString value\\)") + line = 19, + message = "Can't map collection element \"AttributedString\" to \"String \". " + + "Consider to declare/implement a mapping method: \"String map(AttributedString value)\".") } ) public void shouldFailOnNoElementMappingFoundWithDisabledAuto() { } - @Test + @ProcessorTest @IssueKey("459") @WithClasses({ ErroneousCollectionNoKeyMappingFound.class, NoProperties.class, WithProperties.class }) @ExpectedCompilationOutcome( @@ -150,16 +136,16 @@ public void shouldFailOnNoElementMappingFoundWithDisabledAuto() { diagnostics = { @Diagnostic(type = ErroneousCollectionNoKeyMappingFound.class, kind = Kind.ERROR, - line = 38, - messageRegExp = "Can't map Map key \".*WithProperties withProperties\" to \".*NoProperties " + - "noProperties\". Consider to declare/implement a mapping method: \".*NoProperties map\\(" + - ".*WithProperties value\\)") + line = 25, + message = "No target bean properties found: can't map Map key \"WithProperties withProperties\" to " + + "\"NoProperties noProperties\". " + + "Consider to declare/implement a mapping method: \"NoProperties map(WithProperties value)\".") } ) public void shouldFailOnNoKeyMappingFound() { } - @Test + @ProcessorTest @IssueKey("993") @WithClasses({ ErroneousCollectionNoKeyMappingFoundDisabledAuto.class }) @ExpectedCompilationOutcome( @@ -167,15 +153,15 @@ public void shouldFailOnNoKeyMappingFound() { diagnostics = { @Diagnostic(type = ErroneousCollectionNoKeyMappingFoundDisabledAuto.class, kind = Kind.ERROR, - line = 32, - messageRegExp = "Can't map map key \".*AttributedString\" to \".*String \". " + - "Consider to declare/implement a mapping method: \".*String map\\(.*AttributedString value\\)") + line = 19, + message = "Can't map map key \"AttributedString\" to \"String \". Consider to " + + "declare/implement a mapping method: \"String map(AttributedString value)\".") } ) public void shouldFailOnNoKeyMappingFoundWithDisabledAuto() { } - @Test + @ProcessorTest @IssueKey("459") @WithClasses({ ErroneousCollectionNoValueMappingFound.class, NoProperties.class, WithProperties.class }) @ExpectedCompilationOutcome( @@ -183,16 +169,16 @@ public void shouldFailOnNoKeyMappingFoundWithDisabledAuto() { diagnostics = { @Diagnostic(type = ErroneousCollectionNoValueMappingFound.class, kind = Kind.ERROR, - line = 38, - messageRegExp = "Can't map Map value \".*WithProperties withProperties\" to \".*NoProperties " + - "noProperties\". Consider to declare/implement a mapping method: \".*NoProperties map\\(" + - ".*WithProperties value\\)") + line = 25, + message = "No target bean properties found: can't map Map value \"WithProperties withProperties\" " + + "to \"NoProperties noProperties\". " + + "Consider to declare/implement a mapping method: \"NoProperties map(WithProperties value)\".") } ) public void shouldFailOnNoValueMappingFound() { } - @Test + @ProcessorTest @IssueKey("993") @WithClasses({ ErroneousCollectionNoValueMappingFoundDisabledAuto.class }) @ExpectedCompilationOutcome( @@ -200,9 +186,9 @@ public void shouldFailOnNoValueMappingFound() { diagnostics = { @Diagnostic(type = ErroneousCollectionNoValueMappingFoundDisabledAuto.class, kind = Kind.ERROR, - line = 32, - messageRegExp = "Can't map map value \".*AttributedString\" to \".*String \". " + - "Consider to declare/implement a mapping method: \".*String map(.*AttributedString value)") + line = 19, + message = "Can't map map value \"AttributedString\" to \"String \". " + + "Consider to declare/implement a mapping method: \"String map(AttributedString value)\".") } ) public void shouldFailOnNoValueMappingFoundWithDisabledAuto() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFound.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFound.java index 2b153913c2..e3659574ed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFound.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFound.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFoundDisabledAuto.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFoundDisabledAuto.java index 43a159f5bb..aa249cd205 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFoundDisabledAuto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoElementMappingFoundDisabledAuto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFound.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFound.java index 8891b2da92..346124d59f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFound.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFound.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFoundDisabledAuto.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFoundDisabledAuto.java index c0cd8fcb71..ae966e4f5d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFoundDisabledAuto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoKeyMappingFoundDisabledAuto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFound.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFound.java index 9bfd418f31..35caf8f60a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFound.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFound.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFoundDisabledAuto.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFoundDisabledAuto.java index 365c62a757..220ae0a50c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFoundDisabledAuto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionNoValueMappingFoundDisabledAuto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToNonCollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToNonCollectionMapper.java index 40f23f1ac4..0df6a4b95c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToNonCollectionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToNonCollectionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; @@ -28,4 +15,6 @@ public interface ErroneousCollectionToNonCollectionMapper { Integer stringSetToInteger(Set strings); Set integerToStringSet(Integer integer); + + Set nonJavaStdlibToCollection(Source stringCollection); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToPrimitivePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToPrimitivePropertyMapper.java index e753492dad..50a0a4fc0a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToPrimitivePropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/ErroneousCollectionToPrimitivePropertyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Source.java index 7813dfaf82..24a9ce883b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Target.java index 64c8ff77dd..046e92734c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/erroneous/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Bar.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Bar.java index 930058c792..5dfb58c504 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Bar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Bar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapper.java index 19331f3485..39b9d6ce57 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapperNullValueMappingReturnDefault.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapperNullValueMappingReturnDefault.java index 726dec3278..130f281fdb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapperNullValueMappingReturnDefault.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMapperNullValueMappingReturnDefault.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java index 629f74efc1..67cabc9f95 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/CollectionMappingTest.java @@ -1,41 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; - -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Map; - import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; +import com.google.common.collect.ImmutableMap; import org.mapstruct.ap.internal.util.Collections; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -import com.google.common.collect.ImmutableMap; +import static org.assertj.core.api.Assertions.assertThat; /** * Test for mappings between collection types, @@ -43,10 +25,9 @@ * @author Sjaak Derksen */ @IssueKey( "4" ) -@RunWith(AnnotationProcessorTestRunner.class) public class CollectionMappingTest { - @Test + @ProcessorTest @WithClasses({ CollectionMapper.class, Source.class, Target.class }) public void shouldForgeNewIterableMappingMethod() { @@ -65,7 +46,7 @@ public void shouldForgeNewIterableMappingMethod() { assertThat( source2.publicFooSet ).isEqualTo( Collections.asSet( "3", "4" ) ); } - @Test + @ProcessorTest @WithClasses({ CollectionMapper.class, Source.class, Target.class }) public void shouldForgeNewMapMappingMethod() { @@ -87,8 +68,9 @@ public void shouldForgeNewMapMappingMethod() { assertThat( source2.publicBarMap ).isEqualTo( source.publicBarMap ); } - @Test - @WithClasses({ ErroneousCollectionNonMappableSetMapper.class, + @ProcessorTest + @WithClasses({ + ErroneousCollectionNonMappableSetMapper.class, ErroneousNonMappableSetSource.class, ErroneousNonMappableSetTarget.class, Foo.class, @@ -99,15 +81,16 @@ public void shouldForgeNewMapMappingMethod() { diagnostics = { @Diagnostic(type = ErroneousCollectionNonMappableSetMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "Can't map Collection element \".* nonMappableSet\" to \".* nonMappableSet\". " - + "Consider to declare/implement a mapping method: .*."), + line = 17, + message = "No target bean properties found: " + + "can't map Collection element \"Foo nonMappableSet\" to \"Bar nonMappableSet\". " + + "Consider to declare/implement a mapping method: \"Bar map(Foo value)\"."), } ) public void shouldGenerateNonMappleMethodForSetMapping() { } - @Test + @ProcessorTest @WithClasses({ ErroneousCollectionNonMappableMapMapper.class, ErroneousNonMappableMapSource.class, ErroneousNonMappableMapTarget.class, @@ -119,20 +102,22 @@ public void shouldGenerateNonMappleMethodForSetMapping() { diagnostics = { @Diagnostic(type = ErroneousCollectionNonMappableMapMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "Can't map Map key \".* nonMappableMap\\{:key\\}\" to \".* nonMappableMap\\{:key\\}\". " - + "Consider to declare/implement a mapping method: .*."), + line = 17, + message = "No target bean properties found: " + + "can't map Map key \"Foo nonMappableMap{:key}\" to \"Bar nonMappableMap{:key}\". " + + "Consider to declare/implement a mapping method: \"Bar map(Foo value)\"."), @Diagnostic(type = ErroneousCollectionNonMappableMapMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "Can't map Map value \".* nonMappableMap\\{:value\\}\" to \".* " + - "nonMappableMap\\{:value\\}\". Consider to declare/implement a mapping method: .*."), + line = 17, + message = "No target bean properties found: " + + "can't map Map value \"Foo nonMappableMap{:value}\" to \"Bar nonMappableMap{:value}\". " + + "Consider to declare/implement a mapping method: \"Bar map(Foo value)\"."), } ) public void shouldGenerateNonMappleMethodForMapMapping() { } - @Test + @ProcessorTest @IssueKey( "640" ) @WithClasses({ CollectionMapper.class, Source.class, Target.class }) public void shouldForgeNewIterableMappingMethodReturnNullOnNullSource() { @@ -152,7 +137,7 @@ public void shouldForgeNewIterableMappingMethodReturnNullOnNullSource() { assertThat( source2.publicFooSet ).isNull(); } - @Test + @ProcessorTest @IssueKey( "640" ) @WithClasses({ CollectionMapper.class, Source.class, Target.class }) public void shouldForgeNewMapMappingMethodReturnNullOnNullSource() { @@ -172,7 +157,7 @@ public void shouldForgeNewMapMappingMethodReturnNullOnNullSource() { assertThat( source2.publicBarMap ).isNull(); } - @Test + @ProcessorTest @IssueKey( "640" ) @WithClasses({ CollectionMapperNullValueMappingReturnDefault.class, Source.class, Target.class }) public void shouldForgeNewIterableMappingMethodReturnEmptyOnNullSource() { @@ -194,7 +179,7 @@ public void shouldForgeNewIterableMappingMethodReturnEmptyOnNullSource() { assertThat( source2.publicBarMap ).isEmpty(); } - @Test + @ProcessorTest @IssueKey( "640" ) @WithClasses({ CollectionMapperNullValueMappingReturnDefault.class, Source.class, Target.class }) public void shouldForgeNewMapMappingMethodReturnEmptyOnNullSource() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableMapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableMapMapper.java index 76e021f129..bb77390281 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableMapMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableMapMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableSetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableSetMapper.java index 43acb68aeb..94fbed368a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableSetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousCollectionNonMappableSetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapSource.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapSource.java index dd0cf1c490..c00c64f253 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapTarget.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapTarget.java index 648e819b5c..cae62b65a6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableMapTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetSource.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetSource.java index e85c57322a..8a736cda11 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetTarget.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetTarget.java index 7a5d307fcd..701c829112 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/ErroneousNonMappableSetTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Foo.java index aa29236f3d..eb4485ab17 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Source.java index 450d51bdfd..e98dcc37b5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Target.java index 6448efa13e..4a291e5584 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/forged/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardDto.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardDto.java index 10fdda78b7..917ed483ff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.immutabletarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntity.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntity.java index 3579215535..87e9661780 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.immutabletarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntityOnlyGetter.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntityOnlyGetter.java index 1552ccc89e..1f2f2f00b7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntityOnlyGetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardEntityOnlyGetter.java @@ -1,23 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.immutabletarget; +import java.util.ArrayList; import java.util.List; /** @@ -26,7 +14,7 @@ */ public class CupboardEntityOnlyGetter { - private List content; + private List content = new ArrayList<>(); public List getContent() { return content; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardMapper.java index de536286c9..b00f4441c5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.immutabletarget; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardNoSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardNoSetterMapper.java new file mode 100644 index 0000000000..a6674e629f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/CupboardNoSetterMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.immutabletarget; + +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE ) +public interface CupboardNoSetterMapper { + + CupboardNoSetterMapper INSTANCE = Mappers.getMapper( CupboardNoSetterMapper.class ); + + void map( CupboardDto in, @MappingTarget CupboardEntityOnlyGetter out ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ErroneousCupboardMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ErroneousCupboardMapper.java deleted file mode 100644 index 4f59ca7020..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ErroneousCupboardMapper.java +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.collection.immutabletarget; - -import org.mapstruct.CollectionMappingStrategy; -import org.mapstruct.Mapper; -import org.mapstruct.MappingTarget; -import org.mapstruct.factory.Mappers; - -/** - * - * @author Sjaak Derksen - */ -@Mapper( collectionMappingStrategy = CollectionMappingStrategy.TARGET_IMMUTABLE ) -public interface ErroneousCupboardMapper { - - ErroneousCupboardMapper INSTANCE = Mappers.getMapper( ErroneousCupboardMapper.class ); - - void map( CupboardDto in, @MappingTarget CupboardEntityOnlyGetter out ); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ImmutableProductTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ImmutableProductTest.java index 15561a43dd..8097dfdfe9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ImmutableProductTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/immutabletarget/ImmutableProductTest.java @@ -1,53 +1,37 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.immutabletarget; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; import java.util.Collections; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * * @author Sjaak Derksen */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({CupboardDto.class, CupboardEntity.class, CupboardMapper.class}) @IssueKey( "1126" ) public class ImmutableProductTest { - @Test + @ProcessorTest public void shouldHandleImmutableTarget() { CupboardDto in = new CupboardDto(); in.setContent( Arrays.asList( "cups", "soucers" ) ); CupboardEntity out = new CupboardEntity(); - out.setContent( Collections.emptyList() ); + out.setContent( Collections.emptyList() ); CupboardMapper.INSTANCE.map( in, out ); @@ -55,21 +39,26 @@ public void shouldHandleImmutableTarget() { assertThat( out.getContent() ).containsExactly( "cups", "soucers" ); } - @Test + @ProcessorTest @WithClasses({ - ErroneousCupboardMapper.class, + CupboardNoSetterMapper.class, CupboardEntityOnlyGetter.class }) - @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, diagnostics = { - @Diagnostic(type = ErroneousCupboardMapper.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = "No write accessor found for property \"content\" in target type.") - } - ) - public void testShouldFailOnPropertyMappingNoPropertySetterOnlyGetter() { + @Diagnostic(type = CupboardNoSetterMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 22, + message = "No target property found for target \"CupboardEntityOnlyGetter\"."), + }) + public void shouldIgnoreImmutableTarget() { + CupboardDto in = new CupboardDto(); + in.setContent( Arrays.asList( "flour", "peas" ) ); + CupboardEntityOnlyGetter out = new CupboardEntityOnlyGetter(); + out.getContent().add( "bread" ); + CupboardNoSetterMapper.INSTANCE.map( in, out ); + + assertThat( out.getContent() ).containsExactly( "bread" ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/Fruit.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/Fruit.java new file mode 100644 index 0000000000..c989aa4e19 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/Fruit.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletolist; + +/** + * + * @author Xiu-Hong Kooi + */ +public class Fruit { + + private String type; + + public Fruit(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitSalad.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitSalad.java new file mode 100644 index 0000000000..6a04121044 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitSalad.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletolist; + +import java.util.List; + +/** + * + * @author Xiu-Hong Kooi + */ +public class FruitSalad { + + private Iterable fruits; + + public FruitSalad(List fruits) { + this.fruits = fruits; + } + + public Iterable getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitsMapper.java new file mode 100644 index 0000000000..bb4fdc66af --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitsMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletolist; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Xiu-Hong Kooi + */ +@Mapper +public interface FruitsMapper { + + FruitsMapper INSTANCE = Mappers.getMapper( + FruitsMapper.class ); + + FruitsMenu fruitSaladToMenu(FruitSalad salad); + + FruitSalad fruitsMenuToSalad(FruitsMenu menu); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitsMenu.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitsMenu.java new file mode 100644 index 0000000000..6f272dc454 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/FruitsMenu.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletolist; + +import java.util.Iterator; +import java.util.List; + +/** + * + * @author Xiu-Hong Kooi + */ +public class FruitsMenu implements Iterable { + + private List fruits; + + public FruitsMenu(List fruits) { + this.fruits = fruits; + } + + public List getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } + + @Override + public Iterator iterator() { + return this.fruits.iterator(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/IterableToListMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/IterableToListMappingTest.java new file mode 100644 index 0000000000..81a640499b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletolist/IterableToListMappingTest.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletolist; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * + * @author Xiu-Hong Kooi + */ +@WithClasses({ FruitsMenu.class, FruitSalad.class, Fruit.class, FruitsMapper.class }) +public class IterableToListMappingTest { + + @ProcessorTest + @IssueKey("3376") + public void shouldMapIterableToList() { + List fruits = Arrays.asList( new Fruit( "mango" ), new Fruit( "apple" ), + new Fruit( "banana" ) ); + FruitsMenu menu = new FruitsMenu(fruits); + FruitSalad salad = FruitsMapper.INSTANCE.fruitsMenuToSalad( menu ); + Iterator itr = salad.getFruits().iterator(); + assertThat( itr.next().getType() ).isEqualTo( "mango" ); + assertThat( itr.next().getType() ).isEqualTo( "apple" ); + assertThat( itr.next().getType() ).isEqualTo( "banana" ); + } + + @ProcessorTest + @IssueKey("3376") + public void shouldMapListToIterable() { + List fruits = Arrays.asList( new Fruit( "mango" ), new Fruit( "apple" ), + new Fruit( "banana" ) ); + FruitSalad salad = new FruitSalad(fruits); + FruitsMenu menu = FruitsMapper.INSTANCE.fruitSaladToMenu( salad ); + assertThat( menu.getFruits() ).extracting( Fruit::getType ).containsExactly( "mango", "apple", "banana" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Fruit.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Fruit.java new file mode 100644 index 0000000000..f012eb5a84 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Fruit.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletononiterable; + +/** + * + * @author Saheb Preet Singh + */ +public class Fruit { + + private String type; + + public Fruit(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitSalad.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitSalad.java new file mode 100644 index 0000000000..a6298a6095 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitSalad.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletononiterable; + +import java.util.List; + +/** + * + * @author Saheb Preet Singh + */ +public class FruitSalad { + + private List fruits; + + public FruitSalad(List fruits) { + this.fruits = fruits; + } + + public List getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitsMapper.java new file mode 100644 index 0000000000..3d9cc94bad --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitsMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletononiterable; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Saheb Preet Singh + */ +@Mapper +public interface FruitsMapper { + + FruitsMapper INSTANCE = Mappers.getMapper( + FruitsMapper.class ); + + FruitsMenu fruitSaladToMenu(FruitSalad salad); + + FruitSalad fruitsMenuToSalad(FruitsMenu menu); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitsMenu.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitsMenu.java new file mode 100644 index 0000000000..0b1ef94ded --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/FruitsMenu.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletononiterable; + +import java.util.Iterator; +import java.util.List; + +/** + * + * @author Saheb Preet Singh + */ +public class FruitsMenu implements Iterable { + + private List fruits; + + public FruitsMenu(List fruits) { + this.fruits = fruits; + } + + public List getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } + + @Override + public Iterator iterator() { + return this.fruits.iterator(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java index d20c814f7a..7467387d8b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/IterableToNonIterableMappingTest.java @@ -1,38 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.iterabletononiterable; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; +import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -@WithClasses({ Source.class, Target.class, SourceTargetMapper.class, StringListMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ Source.class, Target.class, SourceTargetMapper.class, StringListMapper.class, FruitsMenu.class, + FruitSalad.class, Fruit.class, FruitsMapper.class }) public class IterableToNonIterableMappingTest { - @Test + @ProcessorTest @IssueKey("6") public void shouldMapStringListToStringUsingCustomMapper() { Source source = new Source(); @@ -45,7 +31,7 @@ public void shouldMapStringListToStringUsingCustomMapper() { assertThat( target.publicNames ).isEqualTo( "Alice-Bob-Jim" ); } - @Test + @ProcessorTest @IssueKey("6") public void shouldReverseMapStringListToStringUsingCustomMapper() { Target target = new Target(); @@ -58,4 +44,26 @@ public void shouldReverseMapStringListToStringUsingCustomMapper() { assertThat( source.getNames() ).isEqualTo( Arrays.asList( "Alice", "Bob", "Jim" ) ); assertThat( source.publicNames ).isEqualTo( Arrays.asList( "Alice", "Bob", "Jim" ) ); } + + @ProcessorTest + @IssueKey("607") + public void shouldMapIterableToNonIterable() { + List fruits = Arrays.asList( new Fruit( "mango" ), new Fruit( "apple" ), + new Fruit( "banana" ) ); + FruitsMenu menu = new FruitsMenu(fruits); + FruitSalad salad = FruitsMapper.INSTANCE.fruitsMenuToSalad( menu ); + assertThat( salad.getFruits().get( 0 ).getType() ).isEqualTo( "mango" ); + assertThat( salad.getFruits().get( 1 ).getType() ).isEqualTo( "apple" ); + assertThat( salad.getFruits().get( 2 ).getType() ).isEqualTo( "banana" ); + } + + @ProcessorTest + @IssueKey("607") + public void shouldMapNonIterableToIterable() { + List fruits = Arrays.asList( new Fruit( "mango" ), new Fruit( "apple" ), + new Fruit( "banana" ) ); + FruitSalad salad = new FruitSalad(fruits); + FruitsMenu menu = FruitsMapper.INSTANCE.fruitSaladToMenu( salad ); + assertThat( salad.getFruits() ).extracting( Fruit::getType ).containsExactly( "mango", "apple", "banana" ); + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java index 34ca2264f9..4a757d814f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.iterabletononiterable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java index 714f203339..7395192ac3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.iterabletononiterable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java index d89e0fe1c6..93983acf55 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/StringListMapper.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.iterabletononiterable; import java.util.Arrays; import java.util.List; -import com.google.common.base.Joiner; - public class StringListMapper { public String stringListToString(List strings) { - return strings == null ? null : Joiner.on( "-" ).join( strings ); + return strings == null ? null : String.join( "-", strings ); } public List stringToStringList(String string) { diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java index 2d46d4a0db..07cf6a0f85 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletononiterable/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.iterabletononiterable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/Fruit.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/Fruit.java new file mode 100644 index 0000000000..a15b344908 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/Fruit.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletoset; + +/** + * + * @author Xiu-Hong Kooi + */ +public class Fruit { + + private String type; + + public Fruit(String type) { + this.type = type; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitSalad.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitSalad.java new file mode 100644 index 0000000000..b92ac3160c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitSalad.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletoset; + +import java.util.List; + +/** + * + * @author Xiu-Hong Kooi + */ +public class FruitSalad { + + private Iterable fruits; + + public FruitSalad(Iterable fruits) { + this.fruits = fruits; + } + + public Iterable getFruits() { + return fruits; + } + + public void setFruits(List fruits) { + this.fruits = fruits; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitsMapper.java new file mode 100644 index 0000000000..413dd73617 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitsMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletoset; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Xiu-Hong Kooi + */ +@Mapper +public interface FruitsMapper { + + FruitsMapper INSTANCE = Mappers.getMapper( + FruitsMapper.class ); + + FruitsMenu fruitSaladToMenu(FruitSalad salad); + + FruitSalad fruitsMenuToSalad(FruitsMenu menu); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitsMenu.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitsMenu.java new file mode 100644 index 0000000000..8ae4b8b632 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/FruitsMenu.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletoset; + +import java.util.Iterator; +import java.util.Set; + +/** + * + * @author Xiu-Hong Kooi + */ +public class FruitsMenu implements Iterable { + + private Set fruits; + + public FruitsMenu(Set fruits) { + this.fruits = fruits; + } + + public Set getFruits() { + return fruits; + } + + public void setFruits(Set fruits) { + this.fruits = fruits; + } + + @Override + public Iterator iterator() { + return this.fruits.iterator(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/IterableToSetMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/IterableToSetMappingTest.java new file mode 100644 index 0000000000..0b967503bb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/iterabletoset/IterableToSetMappingTest.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.collection.iterabletoset; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import java.util.stream.Collectors; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * + * @author Xiu-Hong Kooi + */ +@WithClasses({ FruitsMenu.class, FruitSalad.class, Fruit.class, FruitsMapper.class }) +public class IterableToSetMappingTest { + + @ProcessorTest + @IssueKey("3376") + public void shouldMapIterableToSet() { + Set fruits = new HashSet<>( Arrays.asList( new Fruit( "mango" ), new Fruit( "apple" ), + new Fruit( "banana" ) ) ); + FruitsMenu menu = new FruitsMenu(fruits); + FruitSalad salad = FruitsMapper.INSTANCE.fruitsMenuToSalad( menu ); + Iterator itr = salad.getFruits().iterator(); + Set fruitTypes = fruits.stream().map( Fruit::getType ).collect( Collectors.toSet() ); + assertThat( fruitTypes.contains( itr.next().getType() ) ); + assertThat( fruitTypes.contains( itr.next().getType() ) ); + assertThat( fruitTypes.contains( itr.next().getType() ) ); + } + + @ProcessorTest + @IssueKey("3376") + public void shouldMapSetToIterable() { + Set fruits = new HashSet<>( Arrays.asList( new Fruit( "mango" ), new Fruit( "apple" ), + new Fruit( "banana" ) ) ); + FruitSalad salad = new FruitSalad(fruits); + FruitsMenu menu = FruitsMapper.INSTANCE.fruitSaladToMenu( salad ); + assertThat( menu.getFruits() ).extracting( Fruit::getType ).contains( "mango", "apple", "banana" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/map/CustomNumberMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/map/CustomNumberMapper.java index ec6a26e3c5..5fa4de9860 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/map/CustomNumberMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/map/CustomNumberMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.map; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/map/MapMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/map/MapMappingTest.java index c705a7ae46..1261525d4f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/map/MapMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/map/MapMappingTest.java @@ -1,37 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.map; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - +import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.DefaultTimeZone; import org.mapstruct.ap.test.collection.map.other.ImportedType; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; /** * Test for implementation of {@code Map} mapping methods. @@ -40,14 +27,14 @@ */ @WithClasses({ SourceTargetMapper.class, CustomNumberMapper.class, Source.class, Target.class, ImportedType.class }) @IssueKey("44") -@RunWith(AnnotationProcessorTestRunner.class) +@DefaultTimeZone("UTC") public class MapMappingTest { - @Test + @ProcessorTest public void shouldCreateMapMethodImplementation() { - Map values = new HashMap(); - values.put( 42L, new GregorianCalendar( 1980, 0, 1 ).getTime() ); - values.put( 121L, new GregorianCalendar( 2013, 6, 20 ).getTime() ); + Map values = new HashMap<>(); + values.put( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ); + values.put( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ); Map target = SourceTargetMapper.INSTANCE.longDateMapToStringStringMap( values ); @@ -59,7 +46,7 @@ public void shouldCreateMapMethodImplementation() { ); } - @Test + @ProcessorTest public void shouldCreateReverseMapMethodImplementation() { Map values = createStringStringMap(); @@ -68,26 +55,26 @@ public void shouldCreateReverseMapMethodImplementation() { assertResult( target ); } - @Test + @ProcessorTest @IssueKey("19") public void shouldCreateMapMethodImplementationWithTargetParameter() { Map values = createStringStringMap(); - Map target = new HashMap(); - target.put( 66L, new GregorianCalendar( 2013, 7, 16 ).getTime() ); + Map target = new HashMap<>(); + target.put( 66L, new GregorianCalendar( 2013, Calendar.AUGUST, 16 ).getTime() ); SourceTargetMapper.INSTANCE.stringStringMapToLongDateMapUsingTargetParameter( target, values ); assertResult( target ); } - @Test + @ProcessorTest @IssueKey("19") public void shouldCreateMapMethodImplementationWithReturnedTargetParameter() { Map values = createStringStringMap(); - Map target = new HashMap(); - target.put( 66L, new GregorianCalendar( 2013, 7, 16 ).getTime() ); + Map target = new HashMap<>(); + target.put( 66L, new GregorianCalendar( 2013, Calendar.AUGUST, 16 ).getTime() ); Map returnedTarget = SourceTargetMapper.INSTANCE .stringStringMapToLongDateMapUsingTargetParameterAndReturn( values, target ); @@ -97,31 +84,45 @@ public void shouldCreateMapMethodImplementationWithReturnedTargetParameter() { assertResult( target ); } + @ProcessorTest + @IssueKey("1752") + public void shouldCreateMapMethodImplementationWithReturnedTargetParameterAndNullSource() { + Map target = new HashMap<>(); + target.put( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ); + target.put( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ); + + Map returnedTarget = SourceTargetMapper.INSTANCE + .stringStringMapToLongDateMapUsingTargetParameterAndReturn( null, target ); + + assertThat( target ).isSameAs( returnedTarget ); + assertResult( target ); + } + private void assertResult(Map target) { assertThat( target ).isNotNull(); assertThat( target ).hasSize( 2 ); assertThat( target ).contains( - entry( 42L, new GregorianCalendar( 1980, 0, 1 ).getTime() ), - entry( 121L, new GregorianCalendar( 2013, 6, 20 ).getTime() ) + entry( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ), + entry( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ) ); } private Map createStringStringMap() { - Map values = new HashMap(); + Map values = new HashMap<>(); values.put( "42", "01.01.1980" ); values.put( "121", "20.07.2013" ); return values; } - @Test + @ProcessorTest public void shouldInvokeMapMethodImplementationForMapTypedProperty() { - Map values = new HashMap(); - values.put( 42L, new GregorianCalendar( 1980, 0, 1 ).getTime() ); - values.put( 121L, new GregorianCalendar( 2013, 6, 20 ).getTime() ); + Map values = new HashMap<>(); + values.put( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ); + values.put( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ); Source source = new Source(); source.setValues( values ); - source.setPublicValues( new HashMap( values ) ); + source.setPublicValues( new HashMap<>( values ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -142,13 +143,13 @@ public void shouldInvokeMapMethodImplementationForMapTypedProperty() { ); } - @Test + @ProcessorTest public void shouldInvokeReverseMapMethodImplementationForMapTypedProperty() { Map values = createStringStringMap(); Target target = new Target(); target.setValues( values ); - target.publicValues = new HashMap( values ); + target.publicValues = new HashMap<>( values ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -156,27 +157,27 @@ public void shouldInvokeReverseMapMethodImplementationForMapTypedProperty() { assertThat( source.getValues() ).isNotNull(); assertThat( source.getValues() ).hasSize( 2 ); assertThat( source.getValues() ).contains( - entry( 42L, new GregorianCalendar( 1980, 0, 1 ).getTime() ), - entry( 121L, new GregorianCalendar( 2013, 6, 20 ).getTime() ) + entry( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ), + entry( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ) ); assertThat( source.getPublicValues() ) .isNotNull() .hasSize( 2 ) .contains( - entry( 42L, new GregorianCalendar( 1980, 0, 1 ).getTime() ), - entry( 121L, new GregorianCalendar( 2013, 6, 20 ).getTime() ) + entry( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ), + entry( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ) ); } private Map createIntIntMap() { - Map values = new HashMap(); + Map values = new HashMap<>(); values.put( 42, 47 ); values.put( 121, 123 ); return values; } - @Test + @ProcessorTest @IssueKey("87") public void shouldCreateMapMethodImplementationWithoutConversionOrElementMappingMethod() { Map values = createIntIntMap(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/map/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/map/Source.java index af7fc266e7..997e4a8be9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/map/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/map/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.map; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/map/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/map/SourceTargetMapper.java index 94cca06a61..1f996b836e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/map/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/map/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.map; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/map/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/map/Target.java index 282fb27411..db1eee8976 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/map/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/map/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.map; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/map/other/ImportedType.java b/processor/src/test/java/org/mapstruct/ap/test/collection/map/other/ImportedType.java index 4197c678db..91986ca5c0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/map/other/ImportedType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/map/other/ImportedType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.map.other; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/BeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/BeanMapper.java index d759020eb4..42a52eb233 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/BeanMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/BeanMapper.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; import java.math.BigDecimal; - import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; @@ -42,7 +28,7 @@ BigDecimal map(JAXBElement value) { } JAXBElement map(BigDecimal value) { - return new JAXBElement( new QName( "test" ), BigDecimal.class, value ); + return new JAXBElement<>( new QName( "test" ), BigDecimal.class, value ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/CunningPlan.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/CunningPlan.java index 63aaadcae7..b1a901e0f3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/CunningPlan.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/CunningPlan.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; import java.math.BigDecimal; - import javax.xml.bind.JAXBElement; /** diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableExtendsBoundTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableExtendsBoundTargetMapper.java index c45e27aa22..236d24d77b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableExtendsBoundTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableExtendsBoundTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableSuperBoundSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableSuperBoundSourceMapper.java index d22110cb5e..aa29529df9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableSuperBoundSourceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableSuperBoundSourceMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java index c27fe0f904..fbe16cb8e9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java index b7f42bdfa0..d725358997 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSource.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSource.java index 8dad91cd14..8181344d2b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSourceTargetMapper.java index 3df1a5df1c..937cc1f49f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/ExtendsBoundSourceTargetMapper.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/GoodIdea.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/GoodIdea.java index edfdd743e6..9b509e2d10 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/GoodIdea.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/GoodIdea.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; import java.math.BigDecimal; - import javax.xml.bind.JAXBElement; /** diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Idea.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Idea.java index c09ae57a60..4e21b223db 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Idea.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Idea.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; @@ -24,4 +11,13 @@ */ public class Idea { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Plan.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Plan.java index 74724a854b..00db02170c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Plan.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Plan.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; @@ -24,4 +11,13 @@ */ public class Plan { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Source.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Source.java index 6c8e701f6c..1542c7ce96 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SourceSuperBoundTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SourceSuperBoundTargetMapper.java index e80bded7b7..b5bce93345 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SourceSuperBoundTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SourceSuperBoundTargetMapper.java @@ -1,27 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; - /** * * @author Sjaak Derksen diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SuperBoundTarget.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SuperBoundTarget.java index 367872e5c3..7b09752394 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SuperBoundTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/SuperBoundTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Target.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Target.java index c1240d06ea..86b4f001e4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/WildCardTest.java b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/WildCardTest.java index cf6758ece9..4da6f8648a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/WildCardTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/collection/wildcard/WildCardTest.java @@ -1,54 +1,38 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.collection.wildcard; -import static org.assertj.core.api.Assertions.assertThat; - import java.math.BigDecimal; - import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJavaxJaxb; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * Reproducer for https://github.com/mapstruct/mapstruct/issues/527. * * @author Sjaak Derksen */ @IssueKey("527") -@RunWith(AnnotationProcessorTestRunner.class) public class WildCardTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @WithClasses({ ExtendsBoundSourceTargetMapper.class, ExtendsBoundSource.class, @@ -70,7 +54,7 @@ public void shouldGenerateExtendsBoundSourceForgedIterableMethod() { .doesNotContain( "? extends org.mapstruct.ap.test.collection.wildcard.Idea" ); } - @Test + @ProcessorTest @WithClasses({ SourceSuperBoundTargetMapper.class, Source.class, @@ -92,68 +76,69 @@ public void shouldGenerateSuperBoundTargetForgedIterableMethod() { .doesNotContain( "? super org.mapstruct.ap.test.collection.wildcard.Idea" ); } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableSuperBoundSourceMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic( type = ErroneousIterableSuperBoundSourceMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Can't generate mapping method for a wildcard super bound source." ) + line = 20, + message = "Can't generate mapping method for a wildcard super bound source." ) } ) public void shouldFailOnSuperBoundSource() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableExtendsBoundTargetMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic( type = ErroneousIterableExtendsBoundTargetMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Can't generate mapping method for a wildcard extends bound result." ) + line = 20, + message = "Can't generate mapping method for a wildcard extends bound result." ) } ) public void shouldFailOnExtendsBoundTarget() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableTypeVarBoundMapperOnMethod.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousIterableTypeVarBoundMapperOnMethod.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Can't generate mapping method for a generic type variable target." ) + line = 20, + message = "Can't generate mapping method for a generic type variable target." ) } ) public void shouldFailOnTypeVarSource() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableTypeVarBoundMapperOnMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic( type = ErroneousIterableTypeVarBoundMapperOnMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Can't generate mapping method for a generic type variable source." ) + line = 20, + message = "Can't generate mapping method for a generic type variable source." ) } ) public void shouldFailOnTypeVarTarget() { } - @Test + @ProcessorTest @WithClasses( { BeanMapper.class, GoodIdea.class, CunningPlan.class } ) + @WithJavaxJaxb public void shouldMapBean() { GoodIdea aGoodIdea = new GoodIdea(); - aGoodIdea.setContent( new JAXBElement( new QName( "test" ), BigDecimal.class, BigDecimal.ONE ) ); + aGoodIdea.setContent( new JAXBElement<>( new QName( "test" ), BigDecimal.class, BigDecimal.ONE ) ); aGoodIdea.setDescription( BigDecimal.ZERO ); CunningPlan aCunningPlan = BeanMapper.STM.transformA( aGoodIdea ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java index 453dc657d1..b635f6b023 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex; @@ -37,8 +24,8 @@ public interface CarMapper { CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); @Mappings({ - @Mapping(source = "numberOfSeats", target = "seatCount"), - @Mapping(source = "manufacturingDate", target = "manufacturingYear") + @Mapping(target = "seatCount", source = "numberOfSeats"), + @Mapping(target = "manufacturingYear", source = "manufacturingDate") }) CarDto carToCarDto(Car car); diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java index aea64ae581..a1881a7613 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/CarMapperTest.java @@ -1,40 +1,27 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; import java.util.Arrays; +import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.DefaultTimeZone; import org.mapstruct.ap.test.complex._target.CarDto; import org.mapstruct.ap.test.complex._target.PersonDto; import org.mapstruct.ap.test.complex.other.DateMapper; import org.mapstruct.ap.test.complex.source.Car; import org.mapstruct.ap.test.complex.source.Category; import org.mapstruct.ap.test.complex.source.Person; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Car.class, @@ -45,23 +32,23 @@ Category.class, DateMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) +@DefaultTimeZone("UTC") public class CarMapperTest { - @Test - public void shouldProvideMapperInstance() throws Exception { + @ProcessorTest + public void shouldProvideMapperInstance() { assertThat( CarMapper.INSTANCE ).isNotNull(); } - @Test + @ProcessorTest public void shouldMapAttributeByName() { //given Car car = new Car( "Morris", 2, - new GregorianCalendar( 1980, 0, 1 ).getTime(), + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime(), new Person( "Bob" ), - new ArrayList() + new ArrayList<>() ); //when @@ -72,15 +59,15 @@ public void shouldMapAttributeByName() { assertThat( carDto.getMake() ).isEqualTo( car.getMake() ); } - @Test + @ProcessorTest public void shouldMapReferenceAttribute() { //given Car car = new Car( "Morris", 2, - new GregorianCalendar( 1980, 0, 1 ).getTime(), + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime(), new Person( "Bob" ), - new ArrayList() + new ArrayList<>() ); //when @@ -92,10 +79,10 @@ public void shouldMapReferenceAttribute() { assertThat( carDto.getDriver().getName() ).isEqualTo( "Bob" ); } - @Test + @ProcessorTest public void shouldReverseMapReferenceAttribute() { //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); + CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList<>() ); //when Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); @@ -106,15 +93,15 @@ public void shouldReverseMapReferenceAttribute() { assertThat( car.getDriver().getName() ).isEqualTo( "Bob" ); } - @Test + @ProcessorTest public void shouldMapAttributeWithCustomMapping() { //given Car car = new Car( "Morris", 2, - new GregorianCalendar( 1980, 0, 1 ).getTime(), + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime(), new Person( "Bob" ), - new ArrayList() + new ArrayList<>() ); //when @@ -125,10 +112,10 @@ public void shouldMapAttributeWithCustomMapping() { assertThat( carDto.getSeatCount() ).isEqualTo( car.getNumberOfSeats() ); } - @Test + @ProcessorTest public void shouldConsiderCustomMappingForReverseMapping() { //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); + CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList<>() ); //when Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); @@ -138,15 +125,15 @@ public void shouldConsiderCustomMappingForReverseMapping() { assertThat( car.getNumberOfSeats() ).isEqualTo( carDto.getSeatCount() ); } - @Test + @ProcessorTest public void shouldApplyConverter() { //given Car car = new Car( "Morris", 2, - new GregorianCalendar( 1980, 0, 1 ).getTime(), + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime(), new Person( "Bob" ), - new ArrayList() + new ArrayList<>() ); //when @@ -157,39 +144,41 @@ public void shouldApplyConverter() { assertThat( carDto.getManufacturingYear() ).isEqualTo( "1980" ); } - @Test + @ProcessorTest public void shouldApplyConverterForReverseMapping() { //given - CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); + CarDto carDto = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList<>() ); //when Car car = CarMapper.INSTANCE.carDtoToCar( carDto ); //then assertThat( car ).isNotNull(); - assertThat( car.getManufacturingDate() ).isEqualTo( new GregorianCalendar( 1980, 0, 1 ).getTime() ); + assertThat( car.getManufacturingDate() ).isEqualTo( + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() + ); } - @Test + @ProcessorTest public void shouldMapIterable() { //given Car car1 = new Car( "Morris", 2, - new GregorianCalendar( 1980, 0, 1 ).getTime(), + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime(), new Person( "Bob" ), - new ArrayList() + new ArrayList<>() ); Car car2 = new Car( "Railton", 4, - new GregorianCalendar( 1934, 0, 1 ).getTime(), + new GregorianCalendar( 1934, Calendar.JANUARY, 1 ).getTime(), new Person( "Bill" ), - new ArrayList() + new ArrayList<>() ); //when - List dtos = CarMapper.INSTANCE.carsToCarDtos( new ArrayList( Arrays.asList( car1, car2 ) ) ); + List dtos = CarMapper.INSTANCE.carsToCarDtos( Arrays.asList( car1, car2 ) ); //then assertThat( dtos ).isNotNull(); @@ -206,14 +195,14 @@ public void shouldMapIterable() { assertThat( dtos.get( 1 ).getDriver().getName() ).isEqualTo( "Bill" ); } - @Test + @ProcessorTest public void shouldReverseMapIterable() { //given - CarDto car1 = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList() ); - CarDto car2 = new CarDto( "Railton", 4, "1934", new PersonDto( "Bill" ), new ArrayList() ); + CarDto car1 = new CarDto( "Morris", 2, "1980", new PersonDto( "Bob" ), new ArrayList<>() ); + CarDto car2 = new CarDto( "Railton", 4, "1934", new PersonDto( "Bill" ), new ArrayList<>() ); //when - List cars = CarMapper.INSTANCE.carDtosToCars( new ArrayList( Arrays.asList( car1, car2 ) ) ); + List cars = CarMapper.INSTANCE.carDtosToCars( Arrays.asList( car1, car2 ) ); //then assertThat( cars ).isNotNull(); @@ -221,24 +210,28 @@ public void shouldReverseMapIterable() { assertThat( cars.get( 0 ).getMake() ).isEqualTo( "Morris" ); assertThat( cars.get( 0 ).getNumberOfSeats() ).isEqualTo( 2 ); - assertThat( cars.get( 0 ).getManufacturingDate() ).isEqualTo( new GregorianCalendar( 1980, 0, 1 ).getTime() ); + assertThat( cars.get( 0 ).getManufacturingDate() ).isEqualTo( + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() + ); assertThat( cars.get( 0 ).getDriver().getName() ).isEqualTo( "Bob" ); assertThat( cars.get( 1 ).getMake() ).isEqualTo( "Railton" ); assertThat( cars.get( 1 ).getNumberOfSeats() ).isEqualTo( 4 ); - assertThat( cars.get( 1 ).getManufacturingDate() ).isEqualTo( new GregorianCalendar( 1934, 0, 1 ).getTime() ); + assertThat( cars.get( 1 ).getManufacturingDate() ).isEqualTo( + new GregorianCalendar( 1934, Calendar.JANUARY, 1 ).getTime() + ); assertThat( cars.get( 1 ).getDriver().getName() ).isEqualTo( "Bill" ); } - @Test + @ProcessorTest public void shouldMapIterableAttribute() { //given Car car = new Car( "Morris", 2, - new GregorianCalendar( 1980, 0, 1 ).getTime(), + new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime(), new Person( "Bob" ), - new ArrayList( Arrays.asList( new Person( "Alice" ), new Person( "Bill" ) ) ) + Arrays.asList( new Person( "Alice" ), new Person( "Bill" ) ) ); //when @@ -252,7 +245,7 @@ public void shouldMapIterableAttribute() { assertThat( dto.getPassengers().get( 1 ).getName() ).isEqualTo( "Bill" ); } - @Test + @ProcessorTest public void shouldReverseMapIterableAttribute() { //given CarDto carDto = new CarDto( @@ -260,7 +253,7 @@ public void shouldReverseMapIterableAttribute() { 2, "1980", new PersonDto( "Bob" ), - new ArrayList( Arrays.asList( new PersonDto( "Alice" ), new PersonDto( "Bill" ) ) ) + Arrays.asList( new PersonDto( "Alice" ), new PersonDto( "Bill" ) ) ); //when @@ -274,7 +267,7 @@ public void shouldReverseMapIterableAttribute() { assertThat( car.getPassengers().get( 1 ).getName() ).isEqualTo( "Bill" ); } - @Test + @ProcessorTest public void shouldMapEnumToString() { //given Car car = new Car(); @@ -287,7 +280,7 @@ public void shouldMapEnumToString() { assertThat( carDto.getCategory() ).isEqualTo( "CONVERTIBLE" ); } - @Test + @ProcessorTest public void shouldMapStringToEnum() { //given CarDto carDto = new CarDto(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/_target/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/complex/_target/CarDto.java index 30f5166ea2..8878398be7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/_target/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/_target/CarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/_target/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/complex/_target/PersonDto.java index d544b0f0bf..cfe527a9c7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/_target/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/_target/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java index 3df1a8f2bd..3417d5be5f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/other/DateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex.other; diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/source/Car.java b/processor/src/test/java/org/mapstruct/ap/test/complex/source/Car.java index 67317837bf..bfdc4d2c87 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/source/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/source/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/source/Category.java b/processor/src/test/java/org/mapstruct/ap/test/complex/source/Category.java index d5af180698..ca589cf2dd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/source/Category.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/source/Category.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/complex/source/Person.java b/processor/src/test/java/org/mapstruct/ap/test/complex/source/Person.java index 9c3e200112..33dfcc50ca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/complex/source/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/complex/source/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.complex.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/Employee.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/Employee.java new file mode 100644 index 0000000000..ab7cdf4adf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/Employee.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional; + +public class Employee { + private String name; + private String ssid; + private String nin; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSsid() { + return ssid; + } + + public void setSsid(String ssid) { + this.ssid = ssid; + } + + public String getNin() { + return nin; + } + + public void setNin(String nin) { + this.nin = nin; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/EmployeeDto.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/EmployeeDto.java new file mode 100644 index 0000000000..f8b9b319fa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/EmployeeDto.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional; + +public class EmployeeDto { + private String name; + private String country; + private String uniqueIdNumber; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public String getUniqueIdNumber() { + return uniqueIdNumber; + } + + public void setUniqueIdNumber(String uniqueIdNumber) { + this.uniqueIdNumber = uniqueIdNumber; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/BasicEmployee.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/BasicEmployee.java new file mode 100644 index 0000000000..9fcaa6e761 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/BasicEmployee.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployee { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/BasicEmployeeDto.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/BasicEmployeeDto.java new file mode 100644 index 0000000000..24a944137c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/BasicEmployeeDto.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +/** + * @author Filip Hrisafov + */ +public class BasicEmployeeDto { + + private final String name; + private final String strategy; + + public BasicEmployeeDto(String name) { + this( name, "default" ); + } + + public BasicEmployeeDto(String name, String strategy) { + this.name = name; + this.strategy = strategy; + } + + public String getName() { + return name; + } + + public String getStrategy() { + return strategy; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMappingTest.java new file mode 100644 index 0000000000..cb2907fd26 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMappingTest.java @@ -0,0 +1,445 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2051") +@WithClasses({ + BasicEmployee.class, + BasicEmployeeDto.class +}) +public class ConditionalMappingTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapper.class + }) + public void conditionalMethodInMapper() { + generatedSource.addComparisonToFixtureFor( ConditionalMethodInMapper.class ); + ConditionalMethodInMapper mapper = ConditionalMethodInMapper.INSTANCE; + + BasicEmployee employee = mapper.map( new BasicEmployeeDto( "Tester" ) ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + employee = mapper.map( new BasicEmployeeDto( "" ) ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new BasicEmployeeDto( " " ) ); + assertThat( employee.getName() ).isNull(); + } + + @IssueKey( "2882" ) + @ProcessorTest + @WithClasses( { ConditionalMethodWithTargetType.class } ) + public void conditionalMethodWithTargetTypeShouldCompile() { + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodAndBeanPresenceCheckMapper.class + }) + public void conditionalMethodAndBeanPresenceCheckMapper() { + ConditionalMethodAndBeanPresenceCheckMapper mapper = ConditionalMethodAndBeanPresenceCheckMapper.INSTANCE; + + BasicEmployee employee = mapper.map( new ConditionalMethodAndBeanPresenceCheckMapper.EmployeeDto( "Tester" ) ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + employee = mapper.map( new ConditionalMethodAndBeanPresenceCheckMapper.EmployeeDto( "" ) ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new ConditionalMethodAndBeanPresenceCheckMapper.EmployeeDto( " " ) ); + assertThat( employee.getName() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInUsesMapper.class + }) + public void conditionalMethodInUsesMapper() { + ConditionalMethodInUsesMapper mapper = ConditionalMethodInUsesMapper.INSTANCE; + + BasicEmployee employee = mapper.map( new BasicEmployeeDto( "Tester" ) ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + employee = mapper.map( new BasicEmployeeDto( "" ) ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new BasicEmployeeDto( " " ) ); + assertThat( employee.getName() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInUsesStaticMapper.class + }) + public void conditionalMethodInUsesStaticMapper() { + ConditionalMethodInUsesStaticMapper mapper = ConditionalMethodInUsesStaticMapper.INSTANCE; + + BasicEmployee employee = mapper.map( new BasicEmployeeDto( "Tester" ) ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + employee = mapper.map( new BasicEmployeeDto( "" ) ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new BasicEmployeeDto( " " ) ); + assertThat( employee.getName() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInContextMapper.class + }) + public void conditionalMethodInUsesContextMapper() { + ConditionalMethodInContextMapper mapper = ConditionalMethodInContextMapper.INSTANCE; + + ConditionalMethodInContextMapper.PresenceUtils utils = new ConditionalMethodInContextMapper.PresenceUtils(); + BasicEmployee employee = mapper.map( new BasicEmployeeDto( "Tester" ), utils ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + employee = mapper.map( new BasicEmployeeDto( "" ), utils ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new BasicEmployeeDto( " " ), utils ); + assertThat( employee.getName() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithSourceParameterMapper.class + }) + public void conditionalMethodWithSourceParameter() { + ConditionalMethodWithSourceParameterMapper mapper = ConditionalMethodWithSourceParameterMapper.INSTANCE; + + BasicEmployee employee = mapper.map( new BasicEmployeeDto( "Tester" ) ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new BasicEmployeeDto( "Tester", "map" ) ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithSourceParameterAndValueMapper.class + }) + public void conditionalMethodWithSourceParameterAndValue() { + generatedSource.addComparisonToFixtureFor( ConditionalMethodWithSourceParameterAndValueMapper.class ); + ConditionalMethodWithSourceParameterAndValueMapper mapper = + ConditionalMethodWithSourceParameterAndValueMapper.INSTANCE; + + BasicEmployee employee = mapper.map( new BasicEmployeeDto( " ", "empty" ) ); + assertThat( employee.getName() ).isEqualTo( " " ); + + employee = mapper.map( new BasicEmployeeDto( " ", "blank" ) ); + assertThat( employee.getName() ).isNull(); + + employee = mapper.map( new BasicEmployeeDto( "Tester", "blank" ) ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + } + + @ProcessorTest + @WithClasses({ + ErroneousAmbiguousConditionalMethodMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousAmbiguousConditionalMethodMapper.class, + line = 17, + message = "Ambiguous presence check methods found for checking String: " + + "boolean isNotBlank(String value), " + + "boolean isNotEmpty(String value). " + + "See https://mapstruct.org/faq/#ambiguous for more info." + ) + } + ) + public void ambiguousConditionalMethod() { + + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodForCollectionMapper.class + }) + public void conditionalMethodForCollection() { + ConditionalMethodForCollectionMapper mapper = ConditionalMethodForCollectionMapper.INSTANCE; + + ConditionalMethodForCollectionMapper.Author author = new ConditionalMethodForCollectionMapper.Author(); + ConditionalMethodForCollectionMapper.AuthorDto dto = mapper.map( author ); + + assertThat( dto.getBooks() ).isNull(); + + author.setBooks( Collections.emptyList() ); + dto = mapper.map( author ); + + assertThat( dto.getBooks() ).isNull(); + + author.setBooks( Arrays.asList( + new ConditionalMethodForCollectionMapper.Book( "Test" ), + new ConditionalMethodForCollectionMapper.Book( "Test Vol. 2" ) + ) ); + dto = mapper.map( author ); + + assertThat( dto.getBooks() ) + .extracting( ConditionalMethodForCollectionMapper.BookDto::getName ) + .containsExactly( "Test", "Test Vol. 2" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodForSourceBeanMapper.class + }) + public void conditionalMethodForSourceBean() { + ConditionalMethodForSourceBeanMapper mapper = ConditionalMethodForSourceBeanMapper.INSTANCE; + + ConditionalMethodForSourceBeanMapper.Employee employee = mapper.map( + new ConditionalMethodForSourceBeanMapper.EmployeeDto( + "1", + "Tester" + ) ); + + assertThat( employee ).isNotNull(); + assertThat( employee.getId() ).isEqualTo( "1" ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + + employee = mapper.map( null ); + + assertThat( employee ).isNull(); + + employee = mapper.map( new ConditionalMethodForSourceBeanMapper.EmployeeDto( null, "Tester" ) ); + + assertThat( employee ).isNull(); + + employee = mapper.map( new ConditionalMethodForSourceBeanMapper.EmployeeDto( "test-123", "Tester" ) ); + + assertThat( employee ).isNotNull(); + assertThat( employee.getId() ).isEqualTo( "test-123" ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodForSourceParameterAndPropertyMapper.class + }) + public void conditionalMethodForSourceParameterAndProperty() { + ConditionalMethodForSourceParameterAndPropertyMapper mapper = + ConditionalMethodForSourceParameterAndPropertyMapper.INSTANCE; + + ConditionalMethodForSourceParameterAndPropertyMapper.Employee employee = mapper.map( + new ConditionalMethodForSourceParameterAndPropertyMapper.EmployeeDto( + "1", + "Tester" + ) ); + + assertThat( employee ).isNotNull(); + assertThat( employee.getId() ).isEqualTo( "1" ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + assertThat( employee.getManager() ).isNull(); + + employee = mapper.map( null ); + + assertThat( employee ).isNull(); + + employee = mapper.map( new ConditionalMethodForSourceParameterAndPropertyMapper.EmployeeDto( + "1", + "Tester", + new ConditionalMethodForSourceParameterAndPropertyMapper.EmployeeDto( null, "Manager" ) + ) ); + + assertThat( employee ).isNotNull(); + assertThat( employee.getManager() ).isNull(); + + employee = mapper.map( new ConditionalMethodForSourceParameterAndPropertyMapper.EmployeeDto( + "1", + "Tester", + new ConditionalMethodForSourceParameterAndPropertyMapper.EmployeeDto( "2", "Manager" ) + ) ); + + assertThat( employee ).isNotNull(); + assertThat( employee.getId() ).isEqualTo( "1" ); + assertThat( employee.getName() ).isEqualTo( "Tester" ); + assertThat( employee.getManager() ).isNotNull(); + assertThat( employee.getManager().getId() ).isEqualTo( "2" ); + assertThat( employee.getManager().getName() ).isEqualTo( "Manager" ); + } + + @ProcessorTest + @WithClasses({ + OptionalLikeConditionalMapper.class + }) + @IssueKey("2084") + public void optionalLikeConditional() { + OptionalLikeConditionalMapper mapper = OptionalLikeConditionalMapper.INSTANCE; + + OptionalLikeConditionalMapper.Target target = mapper.map( new OptionalLikeConditionalMapper.Source( + OptionalLikeConditionalMapper.Nullable.ofNullable( "test" ) ) ); + + assertThat( target.getValue() ).isEqualTo( "test" ); + + target = mapper.map( + new OptionalLikeConditionalMapper.Source( OptionalLikeConditionalMapper.Nullable.undefined() ) + ); + + assertThat( target.getValue() ).isEqualTo( "initial" ); + + } + + @ProcessorTest + @WithClasses( { + ConditionalMethodWithMappingTargetInUpdateMapper.class + } ) + @IssueKey( "2758" ) + public void conditionalMethodWithMappingTarget() { + ConditionalMethodWithMappingTargetInUpdateMapper mapper = + ConditionalMethodWithMappingTargetInUpdateMapper.INSTANCE; + + BasicEmployee targetEmployee = new BasicEmployee(); + targetEmployee.setName( "CurrentName" ); + mapper.map( new BasicEmployeeDto( "ReplacementName" ), targetEmployee ); + + assertThat( targetEmployee.getName() ).isEqualTo( "CurrentName" ); + } + + @ProcessorTest + @WithClasses({ + ErroneousConditionalWithoutAppliesToMethodMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousConditionalWithoutAppliesToMethodMapper.class, + line = 19, + message = "'appliesTo' has to have at least one value in @Condition" + ) + } + ) + public void emptyConditional() { + } + + @ProcessorTest + @WithClasses({ + ErroneousSourceParameterConditionalWithMappingTargetMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousSourceParameterConditionalWithMappingTargetMapper.class, + line = 21, + message = "Parameter \"@MappingTarget BasicEmployee employee\"" + + " cannot be used with the ConditionStrategy#SOURCE_PARAMETERS." + + " Only source and @Context parameters are allowed for conditions applicable to source parameters." + ) + } + ) + public void sourceParameterConditionalWithMappingTarget() { + } + + @ProcessorTest + @WithClasses({ + ErroneousSourceParameterConditionalWithTargetTypeMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousSourceParameterConditionalWithTargetTypeMapper.class, + line = 21, + message = "Parameter \"@TargetType Class targetClass\"" + + " cannot be used with the ConditionStrategy#SOURCE_PARAMETERS." + + " Only source and @Context parameters are allowed for conditions applicable to source parameters." + ) + } + ) + public void sourceParameterConditionalWithTargetType() { + } + + @ProcessorTest + @WithClasses({ + ErroneousSourceParameterConditionalWithTargetPropertyNameMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousSourceParameterConditionalWithTargetPropertyNameMapper.class, + line = 21, + message = "Parameter \"@TargetPropertyName String targetProperty\"" + + " cannot be used with the ConditionStrategy#SOURCE_PARAMETERS." + + " Only source and @Context parameters are allowed for conditions applicable to source parameters." + ) + } + ) + public void sourceParameterConditionalWithTargetPropertyName() { + } + + @ProcessorTest + @WithClasses({ + ErroneousSourceParameterConditionalWithSourcePropertyNameMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousSourceParameterConditionalWithSourcePropertyNameMapper.class, + line = 21, + message = "Parameter \"@SourcePropertyName String sourceProperty\"" + + " cannot be used with the ConditionStrategy#SOURCE_PARAMETERS." + + " Only source and @Context parameters are allowed for conditions applicable to source parameters." + ) + } + ) + public void sourceParametersConditionalWithSourcePropertyName() { + } + + @ProcessorTest + @WithClasses({ + ErroneousAmbiguousSourceParameterConditionalMethodMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousAmbiguousSourceParameterConditionalMethodMapper.class, + line = 17, + message = "Ambiguous source parameter check methods found for checking BasicEmployeeDto: " + + "boolean hasName(BasicEmployeeDto value), " + + "boolean hasStrategy(BasicEmployeeDto value). " + + "See https://mapstruct.org/faq/#ambiguous for more info." + ) + } + ) + public void ambiguousSourceParameterConditionalMethod() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodAndBeanPresenceCheckMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodAndBeanPresenceCheckMapper.java new file mode 100644 index 0000000000..ad37d5832b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodAndBeanPresenceCheckMapper.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodAndBeanPresenceCheckMapper { + + ConditionalMethodAndBeanPresenceCheckMapper INSTANCE = Mappers.getMapper( + ConditionalMethodAndBeanPresenceCheckMapper.class ); + + BasicEmployee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + class EmployeeDto { + + private final String name; + + public EmployeeDto(String name) { + this.name = name; + } + + public boolean hasName() { + return false; + } + + public String getName() { + return name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForCollectionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForCollectionMapper.java new file mode 100644 index 0000000000..a27a0aaf0a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForCollectionMapper.java @@ -0,0 +1,81 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import java.util.Collection; +import java.util.List; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodForCollectionMapper { + + ConditionalMethodForCollectionMapper INSTANCE = Mappers.getMapper( ConditionalMethodForCollectionMapper.class ); + + AuthorDto map(Author author); + + @Condition + default boolean isNotEmpty(Collection collection) { + return collection != null && !collection.isEmpty(); + } + + class Author { + private List books; + + public List getBooks() { + return books; + } + + public boolean hasBooks() { + return false; + } + + public void setBooks(List books) { + this.books = books; + } + } + + class Book { + private final String name; + + public Book(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class AuthorDto { + private List books; + + public List getBooks() { + return books; + } + + public void setBooks(List books) { + this.books = books; + } + } + + class BookDto { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForSourceBeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForSourceBeanMapper.java new file mode 100644 index 0000000000..dd2fe4ac90 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForSourceBeanMapper.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Mapper; +import org.mapstruct.SourceParameterCondition; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodForSourceBeanMapper { + + ConditionalMethodForSourceBeanMapper INSTANCE = Mappers.getMapper( ConditionalMethodForSourceBeanMapper.class ); + + Employee map(EmployeeDto employee); + + @SourceParameterCondition + default boolean canMapEmployeeDto(EmployeeDto employee) { + return employee != null && employee.getId() != null; + } + + class EmployeeDto { + + private final String id; + private final String name; + + public EmployeeDto(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + } + + class Employee { + + private final String id; + private final String name; + + public Employee(String id, String name) { + this.id = id; + this.name = name; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForSourceParameterAndPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForSourceParameterAndPropertyMapper.java new file mode 100644 index 0000000000..11a97b7239 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodForSourceParameterAndPropertyMapper.java @@ -0,0 +1,85 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.ConditionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodForSourceParameterAndPropertyMapper { + + ConditionalMethodForSourceParameterAndPropertyMapper INSTANCE = Mappers.getMapper( + ConditionalMethodForSourceParameterAndPropertyMapper.class ); + + Employee map(EmployeeDto employee); + + @Condition(appliesTo = { + ConditionStrategy.SOURCE_PARAMETERS, + ConditionStrategy.PROPERTIES + }) + default boolean canMapEmployeeDto(EmployeeDto employee) { + return employee != null && employee.getId() != null; + } + + class EmployeeDto { + + private final String id; + private final String name; + private final EmployeeDto manager; + + public EmployeeDto(String id, String name) { + this( id, name, null ); + } + + public EmployeeDto(String id, String name, EmployeeDto manager) { + this.id = id; + this.name = name; + this.manager = manager; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public EmployeeDto getManager() { + return manager; + } + } + + class Employee { + + private final String id; + private final String name; + private final Employee manager; + + public Employee(String id, String name, Employee manager) { + this.id = id; + this.name = name; + this.manager = manager; + } + + public String getId() { + return id; + } + + public String getName() { + return name; + } + + public Employee getManager() { + return manager; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInContextMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInContextMapper.java new file mode 100644 index 0000000000..26ad844146 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInContextMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodInContextMapper { + + ConditionalMethodInContextMapper INSTANCE = Mappers.getMapper( ConditionalMethodInContextMapper.class ); + + BasicEmployee map(BasicEmployeeDto employee, @Context PresenceUtils utils); + + class PresenceUtils { + @Condition + public boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInMapper.java new file mode 100644 index 0000000000..256419f687 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodInMapper { + + ConditionalMethodInMapper INSTANCE = Mappers.getMapper( ConditionalMethodInMapper.class ); + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition + default boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInUsesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInUsesMapper.java new file mode 100644 index 0000000000..fb30d19c80 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInUsesMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = ConditionalMethodInUsesMapper.PresenceUtils.class) +public interface ConditionalMethodInUsesMapper { + + ConditionalMethodInUsesMapper INSTANCE = Mappers.getMapper( ConditionalMethodInUsesMapper.class ); + + BasicEmployee map(BasicEmployeeDto employee); + + class PresenceUtils { + + @Condition + public boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInUsesStaticMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInUsesStaticMapper.java new file mode 100644 index 0000000000..5e77d6f8fb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodInUsesStaticMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = ConditionalMethodInUsesStaticMapper.PresenceUtils.class) +public interface ConditionalMethodInUsesStaticMapper { + + ConditionalMethodInUsesStaticMapper INSTANCE = Mappers.getMapper( ConditionalMethodInUsesStaticMapper.class ); + + BasicEmployee map(BasicEmployeeDto employee); + + interface PresenceUtils { + + @Condition + static boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithMappingTargetInUpdateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithMappingTargetInUpdateMapper.java new file mode 100644 index 0000000000..12f4a00212 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithMappingTargetInUpdateMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE ) +public interface ConditionalMethodWithMappingTargetInUpdateMapper { + + ConditionalMethodWithMappingTargetInUpdateMapper INSTANCE = + Mappers.getMapper( ConditionalMethodWithMappingTargetInUpdateMapper.class ); + + void map(BasicEmployeeDto employee, @MappingTarget BasicEmployee targetEmployee); + + @Condition + default boolean isNotBlankAndNotPresent(String value, @MappingTarget BasicEmployee targetEmployee) { + return value != null && !value.trim().isEmpty() && targetEmployee.getName() == null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithSourceParameterAndValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithSourceParameterAndValueMapper.java new file mode 100644 index 0000000000..e39c5c88e8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithSourceParameterAndValueMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodWithSourceParameterAndValueMapper { + + ConditionalMethodWithSourceParameterAndValueMapper INSTANCE = Mappers.getMapper( + ConditionalMethodWithSourceParameterAndValueMapper.class ); + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition + default boolean isPresent(BasicEmployeeDto source, String value) { + if ( value == null ) { + return false; + } + switch ( source.getStrategy() ) { + case "blank": + return !value.trim().isEmpty(); + case "empty": + return !value.isEmpty(); + default: + return true; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithSourceParameterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithSourceParameterMapper.java new file mode 100644 index 0000000000..9a499a6039 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithSourceParameterMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodWithSourceParameterMapper { + + ConditionalMethodWithSourceParameterMapper INSTANCE = + Mappers.getMapper( ConditionalMethodWithSourceParameterMapper.class ); + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition + default boolean shouldMap(BasicEmployeeDto source) { + return "map".equals( source.getStrategy() ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithTargetType.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithTargetType.java new file mode 100644 index 0000000000..5ec242d8ff --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ConditionalMethodWithTargetType.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.TargetType; +import org.mapstruct.factory.Mappers; + +/** + * @author Ben Zegveld + */ +@Mapper +public interface ConditionalMethodWithTargetType { + + ConditionalMethodWithTargetType INSTANCE = Mappers.getMapper( ConditionalMethodWithTargetType.class ); + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition + default boolean isNotBlank(String value, @TargetType Class targetType) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousAmbiguousConditionalMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousAmbiguousConditionalMethodMapper.java new file mode 100644 index 0000000000..49e354c913 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousAmbiguousConditionalMethodMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousAmbiguousConditionalMethodMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition + default boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + @Condition + default boolean isNotEmpty(String value) { + return value != null && value.isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousAmbiguousSourceParameterConditionalMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousAmbiguousSourceParameterConditionalMethodMapper.java new file mode 100644 index 0000000000..39433e2641 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousAmbiguousSourceParameterConditionalMethodMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Mapper; +import org.mapstruct.SourceParameterCondition; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousAmbiguousSourceParameterConditionalMethodMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @SourceParameterCondition + default boolean hasName(BasicEmployeeDto value) { + return value != null && value.getName() != null; + } + + @SourceParameterCondition + default boolean hasStrategy(BasicEmployeeDto value) { + return value != null && value.getStrategy() != null; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousConditionalWithoutAppliesToMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousConditionalWithoutAppliesToMethodMapper.java new file mode 100644 index 0000000000..76f62845d5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousConditionalWithoutAppliesToMethodMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousConditionalWithoutAppliesToMethodMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition(appliesTo = {}) + default boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithMappingTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithMappingTargetMapper.java new file mode 100644 index 0000000000..b1206798d6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithMappingTargetMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.ConditionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousSourceParameterConditionalWithMappingTargetMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition(appliesTo = ConditionStrategy.SOURCE_PARAMETERS) + default boolean isNotBlank(String value, @MappingTarget BasicEmployee employee) { + return value != null && !value.trim().isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithSourcePropertyNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithSourcePropertyNameMapper.java new file mode 100644 index 0000000000..1bfd150afc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithSourcePropertyNameMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.ConditionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.SourcePropertyName; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousSourceParameterConditionalWithSourcePropertyNameMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition(appliesTo = ConditionStrategy.SOURCE_PARAMETERS) + default boolean isNotBlank(String value, @SourcePropertyName String sourceProperty) { + return value != null && !value.trim().isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithTargetPropertyNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithTargetPropertyNameMapper.java new file mode 100644 index 0000000000..e9dac1ece5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithTargetPropertyNameMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.ConditionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.TargetPropertyName; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousSourceParameterConditionalWithTargetPropertyNameMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition(appliesTo = ConditionStrategy.SOURCE_PARAMETERS) + default boolean isNotBlank(String value, @TargetPropertyName String targetProperty) { + return value != null && !value.trim().isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithTargetTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithTargetTypeMapper.java new file mode 100644 index 0000000000..9ff55597ae --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/ErroneousSourceParameterConditionalWithTargetTypeMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.ConditionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.TargetType; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousSourceParameterConditionalWithTargetTypeMapper { + + BasicEmployee map(BasicEmployeeDto employee); + + @Condition(appliesTo = ConditionStrategy.SOURCE_PARAMETERS) + default boolean isNotBlank(String value, @TargetType Class targetClass) { + return value != null && !value.trim().isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/OptionalLikeConditionalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/OptionalLikeConditionalMapper.java new file mode 100644 index 0000000000..4d097d7b5f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/basic/OptionalLikeConditionalMapper.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.basic; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface OptionalLikeConditionalMapper { + + OptionalLikeConditionalMapper INSTANCE = Mappers.getMapper( OptionalLikeConditionalMapper.class ); + + Target map(Source source); + + default T map(Nullable nullable) { + return nullable.value; + } + + @Condition + default boolean isPresent(Nullable nullable) { + return nullable.isPresent(); + } + + class Nullable { + + private final T value; + private final boolean present; + + private Nullable(T value, boolean present) { + this.value = value; + this.present = present; + } + + public boolean isPresent() { + return present; + } + + public static Nullable undefined() { + return new Nullable<>( null, false ); + } + + public static Nullable ofNullable(T value) { + return new Nullable<>( value, true ); + } + } + + class Source { + protected final Nullable value; + + public Source(Nullable value) { + this.value = value; + } + + public Nullable getValue() { + return value; + } + } + + class Target { + protected String value = "initial"; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalExpressionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalExpressionTest.java new file mode 100644 index 0000000000..1ad36f7de1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalExpressionTest.java @@ -0,0 +1,144 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.expression; + +import org.mapstruct.ap.test.conditional.Employee; +import org.mapstruct.ap.test.conditional.EmployeeDto; +import org.mapstruct.ap.test.conditional.basic.BasicEmployee; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2051") +@WithClasses({ + Employee.class, + EmployeeDto.class +}) +public class ConditionalExpressionTest { + + @ProcessorTest + @WithClasses({ + ConditionalMethodsInUtilClassMapper.class + }) + public void conditionalExpressionInStaticClassMethod() { + ConditionalMethodsInUtilClassMapper mapper = ConditionalMethodsInUtilClassMapper.INSTANCE; + + EmployeeDto dto = new EmployeeDto(); + dto.setName( "Tester" ); + dto.setUniqueIdNumber( "SSID-001" ); + dto.setCountry( null ); + + Employee employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isNull(); + + dto.setCountry( "UK" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isEqualTo( "SSID-001" ); + assertThat( employee.getSsid() ).isNull(); + + dto.setCountry( "US" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isEqualTo( "SSID-001" ); + + dto.setCountry( "CH" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + SimpleConditionalExpressionMapper.class + }) + public void conditionalSimpleExpression() { + SimpleConditionalExpressionMapper mapper = SimpleConditionalExpressionMapper.INSTANCE; + + SimpleConditionalExpressionMapper.Target target = + mapper.map( new SimpleConditionalExpressionMapper.Source( 50 ) ); + assertThat( target.getValue() ).isEqualTo( 50 ); + + target = mapper.map( new SimpleConditionalExpressionMapper.Source( 101 ) ); + assertThat( target.getValue() ).isEqualTo( 0 ); + } + + @ProcessorTest + @WithClasses({ + ConditionalWithSourceToTargetExpressionMapper.class + }) + @IssueKey("2666") + public void conditionalExpressionForSourceToTarget() { + ConditionalWithSourceToTargetExpressionMapper mapper = ConditionalWithSourceToTargetExpressionMapper.INSTANCE; + + ConditionalWithSourceToTargetExpressionMapper.OrderDTO orderDto = + new ConditionalWithSourceToTargetExpressionMapper.OrderDTO(); + + ConditionalWithSourceToTargetExpressionMapper.Order order = mapper.convertToOrder( orderDto ); + assertThat( order ).isNotNull(); + assertThat( order.getCustomer() ).isNull(); + + orderDto = new ConditionalWithSourceToTargetExpressionMapper.OrderDTO(); + orderDto.setCustomerName( "Tester" ); + order = mapper.convertToOrder( orderDto ); + + assertThat( order ).isNotNull(); + assertThat( order.getCustomer() ).isNotNull(); + assertThat( order.getCustomer().getName() ).isEqualTo( "Tester" ); + assertThat( order.getCustomer().getAddress() ).isNull(); + + orderDto = new ConditionalWithSourceToTargetExpressionMapper.OrderDTO(); + orderDto.setLine1( "Line 1" ); + order = mapper.convertToOrder( orderDto ); + + assertThat( order ).isNotNull(); + assertThat( order.getCustomer() ).isNotNull(); + assertThat( order.getCustomer().getName() ).isNull(); + assertThat( order.getCustomer().getAddress() ).isNotNull(); + assertThat( order.getCustomer().getAddress().getLine1() ).isEqualTo( "Line 1" ); + assertThat( order.getCustomer().getAddress().getLine2() ).isNull(); + + } + + @IssueKey("2794") + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousConditionExpressionMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 19, + message = "Value for condition expression must be given in the form \"java()\"." + ), + @Diagnostic(type = ErroneousConditionExpressionMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 22, + message = "Constant and condition expression are both defined in @Mapping," + + " either define a constant or a condition expression." + ), + @Diagnostic(type = ErroneousConditionExpressionMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 25, + message = "Expression and condition expression are both defined in @Mapping," + + " either define an expression or a condition expression." + ) + } + ) + @WithClasses({ + BasicEmployee.class, + ErroneousConditionExpressionMapper.class + } ) + public void invalidJavaConditionExpression() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalMethodsInUtilClassMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalMethodsInUtilClassMapper.java new file mode 100644 index 0000000000..3c49de5bf0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalMethodsInUtilClassMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.expression; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.conditional.Employee; +import org.mapstruct.ap.test.conditional.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(imports = ConditionalMethodsInUtilClassMapper.StaticUtil.class) +public interface ConditionalMethodsInUtilClassMapper { + + ConditionalMethodsInUtilClassMapper INSTANCE = Mappers.getMapper( ConditionalMethodsInUtilClassMapper.class ); + + @Mapping(target = "ssid", source = "uniqueIdNumber", + conditionExpression = "java(StaticUtil.isAmericanCitizen( employee ))") + @Mapping(target = "nin", source = "uniqueIdNumber", + conditionExpression = "java(StaticUtil.isBritishCitizen( employee ))") + Employee map(EmployeeDto employee); + + interface StaticUtil { + + static boolean isAmericanCitizen(EmployeeDto employeeDto) { + return "US".equals( employeeDto.getCountry() ); + } + + static boolean isBritishCitizen(EmployeeDto employeeDto) { + return "UK".equals( employeeDto.getCountry() ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalWithSourceToTargetExpressionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalWithSourceToTargetExpressionMapper.java new file mode 100644 index 0000000000..c32fe99e03 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ConditionalWithSourceToTargetExpressionMapper.java @@ -0,0 +1,132 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.expression; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(imports = ConditionalWithSourceToTargetExpressionMapper.Util.class) +public interface ConditionalWithSourceToTargetExpressionMapper { + + ConditionalWithSourceToTargetExpressionMapper INSTANCE = + Mappers.getMapper( ConditionalWithSourceToTargetExpressionMapper.class ); + + @Mapping(source = "orderDTO", target = "customer", + conditionExpression = "java(Util.mapCustomerFromOrder( orderDTO ))") + Order convertToOrder(OrderDTO orderDTO); + + @Mapping(source = "customerName", target = "name") + @Mapping(source = "orderDTO", target = "address", + conditionExpression = "java(Util.mapAddressFromOrder( orderDTO ))") + Customer convertToCustomer(OrderDTO orderDTO); + + Address convertToAddress(OrderDTO orderDTO); + + class OrderDTO { + + private String customerName; + private String line1; + private String line2; + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } + + } + + class Order { + + private Customer customer; + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + } + + class Customer { + private String name; + private Address address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + } + + class Address { + + private String line1; + private String line2; + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } + } + + interface Util { + + static boolean mapCustomerFromOrder(OrderDTO orderDTO) { + return orderDTO != null && ( orderDTO.getCustomerName() != null || mapAddressFromOrder( orderDTO ) ); + } + + static boolean mapAddressFromOrder(OrderDTO orderDTO) { + return orderDTO != null && ( orderDTO.getLine1() != null || orderDTO.getLine2() != null ); + } + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ErroneousConditionExpressionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ErroneousConditionExpressionMapper.java new file mode 100644 index 0000000000..c8e5db243e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/ErroneousConditionExpressionMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.expression; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.conditional.EmployeeDto; +import org.mapstruct.ap.test.conditional.basic.BasicEmployee; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousConditionExpressionMapper { + + @Mapping(target = "name", conditionExpression = "!employee.getName().isEmpty()") + BasicEmployee map(EmployeeDto employee); + + @Mapping(target = "name", conditionExpression = "java(true)", constant = "test") + BasicEmployee mapConstant(EmployeeDto employee); + + @Mapping(target = "name", conditionExpression = "java(true)", expression = "java(\"test\")") + BasicEmployee mapExpression(EmployeeDto employee); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/SimpleConditionalExpressionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/SimpleConditionalExpressionMapper.java new file mode 100644 index 0000000000..861fa0c1e3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/expression/SimpleConditionalExpressionMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.expression; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleConditionalExpressionMapper { + + SimpleConditionalExpressionMapper INSTANCE = Mappers.getMapper( SimpleConditionalExpressionMapper.class ); + + @Mapping(target = "value", conditionExpression = "java(source.getValue() < 100)") + Target map(Source source); + + class Source { + private final int value; + + public Source(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + } + + class Target { + private int value; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/Address.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/Address.java new file mode 100644 index 0000000000..339af75944 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/Address.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname; + +/** + * @author Nikola Ivačič + */ +public class Address implements DomainModel { + private String street; + + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/AddressDto.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/AddressDto.java new file mode 100644 index 0000000000..c6a63065d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/AddressDto.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname; + +/** + * @author Nikola Ivačič + */ +public class AddressDto implements DomainModel { + private final String street; + + public AddressDto(String street) { + this.street = street; + } + + public String getStreet() { + return street; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/DomainModel.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/DomainModel.java new file mode 100644 index 0000000000..8e5fa8695d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/DomainModel.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname; + +/** + * Target Property Name test entities + * + * @author Nikola Ivačič + */ +public interface DomainModel { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/Employee.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/Employee.java new file mode 100644 index 0000000000..497717a592 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/Employee.java @@ -0,0 +1,99 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname; + +import java.util.List; + +/** + * @author Nikola Ivačič + */ +public class Employee implements DomainModel { + + private String firstName; + private String lastName; + private String title; + private String country; + private boolean active; + private int age; + + private Employee boss; + + private Address primaryAddress; + + private List

      addresses; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public Employee getBoss() { + return boss; + } + + public void setBoss(Employee boss) { + this.boss = boss; + } + + public Address getPrimaryAddress() { + return primaryAddress; + } + + public void setPrimaryAddress(Address primaryAddress) { + this.primaryAddress = primaryAddress; + } + + public List
      getAddresses() { + return addresses; + } + + public void setAddresses(List
      addresses) { + this.addresses = addresses; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/EmployeeDto.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/EmployeeDto.java new file mode 100644 index 0000000000..f49f25e4a3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/EmployeeDto.java @@ -0,0 +1,98 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname; + +import java.util.List; + +/** + * @author Nikola Ivačič + */ +public class EmployeeDto implements DomainModel { + + private String firstName; + private String lastName; + private String title; + private String originCountry; + private boolean active; + private int age; + + private EmployeeDto boss; + + private AddressDto primaryAddress; + private List originAddresses; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getOriginCountry() { + return originCountry; + } + + public void setOriginCountry(String originCountry) { + this.originCountry = originCountry; + } + + public boolean isActive() { + return active; + } + + public void setActive(boolean active) { + this.active = active; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public EmployeeDto getBoss() { + return boss; + } + + public void setBoss(EmployeeDto boss) { + this.boss = boss; + } + + public AddressDto getPrimaryAddress() { + return primaryAddress; + } + + public void setPrimaryAddress(AddressDto primaryAddress) { + this.primaryAddress = primaryAddress; + } + + public List getOriginAddresses() { + return originAddresses; + } + + public void setOriginAddresses(List originAddresses) { + this.originAddresses = originAddresses; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodForCollectionMapperWithSourcePropertyName.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodForCollectionMapperWithSourcePropertyName.java new file mode 100644 index 0000000000..944fe5d146 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodForCollectionMapperWithSourcePropertyName.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import java.util.Collection; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@Mapper +public interface ConditionalMethodForCollectionMapperWithSourcePropertyName { + + ConditionalMethodForCollectionMapperWithSourcePropertyName INSTANCE + = Mappers.getMapper( ConditionalMethodForCollectionMapperWithSourcePropertyName.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotEmpty(Collection collection, @SourcePropertyName String propName) { + if ( "originAddresses".equalsIgnoreCase( propName ) ) { + return false; + } + return collection != null && !collection.isEmpty(); + } + + @Condition + default boolean isNotBlank(String value, @SourcePropertyName String propName) { + if ( propName.equalsIgnoreCase( "originCountry" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithAllExceptTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithAllExceptTarget.java new file mode 100644 index 0000000000..ea6a77d94e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithAllExceptTarget.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@Mapper +public interface ConditionalMethodInMapperWithAllExceptTarget { + + ConditionalMethodInMapperWithAllExceptTarget INSTANCE + = Mappers.getMapper( ConditionalMethodInMapperWithAllExceptTarget.class ); + + class PresenceUtils { + Set visited = new LinkedHashSet<>(); + Set visitedSources = new LinkedHashSet<>(); + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtils utils); + + @Condition + default boolean isNotBlank(String value, + DomainModel source, + @SourcePropertyName String propName, + @Context PresenceUtils utils) { + utils.visited.add( propName ); + utils.visitedSources.add( source.getClass().getSimpleName() ); + if ( propName.equalsIgnoreCase( "firstName" ) ) { + return true; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithAllOptions.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithAllOptions.java new file mode 100644 index 0000000000..ee3be57648 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithAllOptions.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@Mapper +public interface ConditionalMethodInMapperWithAllOptions { + + ConditionalMethodInMapperWithAllOptions INSTANCE + = Mappers.getMapper( ConditionalMethodInMapperWithAllOptions.class ); + + class PresenceUtils { + Set visitedSourceNames = new LinkedHashSet<>(); + Set visitedTargetNames = new LinkedHashSet<>(); + Set visitedSources = new LinkedHashSet<>(); + Set visitedTargets = new LinkedHashSet<>(); + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + void map(EmployeeDto employeeDto, + @MappingTarget Employee employee, + @Context PresenceUtils utils); + + @Condition + default boolean isNotBlank(String value, + DomainModel source, + @MappingTarget DomainModel target, + @SourcePropertyName String sourcePropName, + @TargetPropertyName String targetPropName, + @Context PresenceUtils utils) { + utils.visitedSourceNames.add( sourcePropName ); + utils.visitedTargetNames.add( targetPropName ); + utils.visitedSources.add( source.getClass().getSimpleName() ); + utils.visitedTargets.add( target.getClass().getSimpleName() ); + if ( sourcePropName.equalsIgnoreCase( "lastName" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithSourcePropertyName.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithSourcePropertyName.java new file mode 100644 index 0000000000..41ff6c5264 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInMapperWithSourcePropertyName.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@Mapper +public interface ConditionalMethodInMapperWithSourcePropertyName { + + ConditionalMethodInMapperWithSourcePropertyName INSTANCE + = Mappers.getMapper( ConditionalMethodInMapperWithSourcePropertyName.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value, @SourcePropertyName String propName) { + if ( propName.equalsIgnoreCase( "originCountry" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInUsesMapperWithSourcePropertyName.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInUsesMapperWithSourcePropertyName.java new file mode 100644 index 0000000000..8ba222512f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodInUsesMapperWithSourcePropertyName.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@Mapper(uses = ConditionalMethodInUsesMapperWithSourcePropertyName.PresenceUtils.class) +public interface ConditionalMethodInUsesMapperWithSourcePropertyName { + + ConditionalMethodInUsesMapperWithSourcePropertyName INSTANCE + = Mappers.getMapper( ConditionalMethodInUsesMapperWithSourcePropertyName.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + class PresenceUtils { + + @Condition + public boolean isNotBlank(String value, @SourcePropertyName String propName) { + if ( propName.equalsIgnoreCase( "originCountry" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodWithSourcePropertyNameInContextMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodWithSourcePropertyNameInContextMapper.java new file mode 100644 index 0000000000..f69695baa0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ConditionalMethodWithSourcePropertyNameInContextMapper.java @@ -0,0 +1,108 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import java.util.Deque; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.TargetType; +import org.mapstruct.ap.test.conditional.propertyname.Address; +import org.mapstruct.ap.test.conditional.propertyname.AddressDto; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@Mapper +public interface ConditionalMethodWithSourcePropertyNameInContextMapper { + + ConditionalMethodWithSourcePropertyNameInContextMapper INSTANCE + = Mappers.getMapper( ConditionalMethodWithSourcePropertyNameInContextMapper.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtils utils); + + Address map(AddressDto addressDto, @Context PresenceUtils utils); + + class PresenceUtils { + Set visited = new LinkedHashSet<>(); + + @Condition + public boolean isNotBlank(String value, @SourcePropertyName String propName) { + visited.add( propName ); + return value != null && !value.trim().isEmpty(); + } + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtilsAllProps utils); + + Address map(AddressDto addressDto, @Context PresenceUtilsAllProps utils); + + class PresenceUtilsAllProps { + Set visited = new LinkedHashSet<>(); + + @Condition + public boolean collect(@SourcePropertyName String propName) { + visited.add( propName ); + return true; + } + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtilsAllPropsWithSource utils); + + Address map(AddressDto addressDto, @Context PresenceUtilsAllPropsWithSource utils); + + @BeforeMapping + default void before(DomainModel source, @Context PresenceUtilsAllPropsWithSource utils) { + String lastProp = utils.visitedSegments.peekLast(); + if ( lastProp != null && source != null ) { + utils.path.offerLast( lastProp ); + } + } + + @AfterMapping + default void after(@TargetType Class targetClass, @Context PresenceUtilsAllPropsWithSource utils) { + // intermediate method for collection mapping must not change the path + if ( targetClass != List.class ) { + utils.path.pollLast(); + } + } + + class PresenceUtilsAllPropsWithSource { + Deque visitedSegments = new LinkedList<>(); + Deque visited = new LinkedList<>(); + Deque path = new LinkedList<>(); + + @Condition + public boolean collect(@SourcePropertyName String propName) { + visitedSegments.offerLast( propName ); + path.offerLast( propName ); + visited.offerLast( String.join( ".", path ) ); + path.pollLast(); + return true; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ErroneousNonStringSourcePropertyNameParameter.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ErroneousNonStringSourcePropertyNameParameter.java new file mode 100644 index 0000000000..5ed118676d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/ErroneousNonStringSourcePropertyNameParameter.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; + +@Mapper +public interface ErroneousNonStringSourcePropertyNameParameter { + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value, @SourcePropertyName int propName) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/SourcePropertyNameTest.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/SourcePropertyNameTest.java new file mode 100644 index 0000000000..2471ed647d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/sourcepropertyname/SourcePropertyNameTest.java @@ -0,0 +1,312 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.sourcepropertyname; + +import java.util.Collections; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.conditional.propertyname.Address; +import org.mapstruct.ap.test.conditional.propertyname.AddressDto; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + * @author Mohammad Al Zouabi + * @author Oliver Erhart + */ +@IssueKey("3323") +@WithClasses({ + Address.class, + AddressDto.class, + Employee.class, + EmployeeDto.class, + DomainModel.class +}) +public class SourcePropertyNameTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapperWithSourcePropertyName.class + }) + public void conditionalMethodInMapperWithSourcePropertyName() { + ConditionalMethodInMapperWithSourcePropertyName mapper + = ConditionalMethodInMapperWithSourcePropertyName.INSTANCE; + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto ); + assertThat( employee.getLastName() ).isEqualTo( "Testirovich" ); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isNull(); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodForCollectionMapperWithSourcePropertyName.class + }) + public void conditionalMethodForCollectionMapperWithSourcePropertyName() { + ConditionalMethodForCollectionMapperWithSourcePropertyName mapper + = ConditionalMethodForCollectionMapperWithSourcePropertyName.INSTANCE; + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto ); + assertThat( employee.getLastName() ).isEqualTo( "Testirovich" ); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isNull(); + assertThat( employee.getAddresses() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInUsesMapperWithSourcePropertyName.class + }) + public void conditionalMethodInUsesMapperWithSourcePropertyName() { + ConditionalMethodInUsesMapperWithSourcePropertyName mapper + = ConditionalMethodInUsesMapperWithSourcePropertyName.INSTANCE; + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto ); + assertThat( employee.getLastName() ).isEqualTo( "Testirovich" ); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isNull(); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapperWithAllOptions.class + }) + public void conditionalMethodInMapperWithAllOptions() { + ConditionalMethodInMapperWithAllOptions mapper + = ConditionalMethodInMapperWithAllOptions.INSTANCE; + + ConditionalMethodInMapperWithAllOptions.PresenceUtils utils = + new ConditionalMethodInMapperWithAllOptions.PresenceUtils(); + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = new Employee(); + mapper.map( employeeDto, employee, utils ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( utils.visitedSourceNames ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "originCountry" ); + assertThat( utils.visitedTargetNames ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "country" ); + assertThat( utils.visitedSources ).containsExactly( "EmployeeDto" ); + assertThat( utils.visitedTargets ).containsExactly( "Employee" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapperWithAllExceptTarget.class + }) + public void conditionalMethodInMapperWithAllExceptTarget() { + ConditionalMethodInMapperWithAllExceptTarget mapper + = ConditionalMethodInMapperWithAllExceptTarget.INSTANCE; + + ConditionalMethodInMapperWithAllExceptTarget.PresenceUtils utils = + new ConditionalMethodInMapperWithAllExceptTarget.PresenceUtils(); + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto, utils ); + assertThat( employee.getLastName() ).isEqualTo( "Testirovich" ); + assertThat( employee.getFirstName() ).isEqualTo( " " ); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( utils.visited ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "originCountry", "street" ); + assertThat( utils.visitedSources ).containsExactlyInAnyOrder( "EmployeeDto", "AddressDto" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithSourcePropertyNameInContextMapper.class + }) + public void conditionalMethodWithSourcePropertyNameInUsesContextMapper() { + ConditionalMethodWithSourcePropertyNameInContextMapper mapper + = ConditionalMethodWithSourcePropertyNameInContextMapper.INSTANCE; + + ConditionalMethodWithSourcePropertyNameInContextMapper.PresenceUtils utils = + new ConditionalMethodWithSourcePropertyNameInContextMapper.PresenceUtils(); + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setLastName( " " ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto, utils ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( utils.visited ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "originCountry", "street" ); + + ConditionalMethodWithSourcePropertyNameInContextMapper.PresenceUtilsAllProps allPropsUtils = + new ConditionalMethodWithSourcePropertyNameInContextMapper.PresenceUtilsAllProps(); + + employeeDto = new EmployeeDto(); + employeeDto.setLastName( "Tester" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + employee = mapper.map( employeeDto, allPropsUtils ); + assertThat( employee.getLastName() ).isEqualTo( "Tester" ); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( allPropsUtils.visited ) + .containsExactlyInAnyOrder( + "firstName", + "lastName", + "title", + "originCountry", + "active", + "age", + "boss", + "primaryAddress", + "originAddresses", + "street" + ); + + ConditionalMethodWithSourcePropertyNameInContextMapper.PresenceUtilsAllPropsWithSource allPropsUtilsWithSource = + new ConditionalMethodWithSourcePropertyNameInContextMapper.PresenceUtilsAllPropsWithSource(); + + EmployeeDto bossEmployeeDto = new EmployeeDto(); + bossEmployeeDto.setLastName( "Boss Tester" ); + bossEmployeeDto.setOriginCountry( "US" ); + bossEmployeeDto.setOriginAddresses( Collections.singletonList( new AddressDto( + "Testing St. 10" ) ) ); + + employeeDto = new EmployeeDto(); + employeeDto.setLastName( "Tester" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setBoss( bossEmployeeDto ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + employee = mapper.map( employeeDto, allPropsUtilsWithSource ); + assertThat( employee.getLastName() ).isEqualTo( "Tester" ); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ).isNotEmpty(); + assertThat( employee.getAddresses().get( 0 ).getStreet() ).isEqualTo( "Testing St. 6" ); + assertThat( employee.getBoss() ).isNotNull(); + assertThat( employee.getBoss().getCountry() ).isEqualTo( "US" ); + assertThat( employee.getBoss().getLastName() ).isEqualTo( "Boss Tester" ); + assertThat( employee.getBoss().getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 10" ); + assertThat( allPropsUtilsWithSource.visited ) + .containsExactly( + "originCountry", + "originAddresses", + "originAddresses.street", + "firstName", + "lastName", + "title", + "active", + "age", + "boss", + "boss.originCountry", + "boss.originAddresses", + "boss.originAddresses.street", + "boss.firstName", + "boss.lastName", + "boss.title", + "boss.active", + "boss.age", + "boss.boss", + "boss.primaryAddress", + "primaryAddress" + ); + } + + @ProcessorTest + @WithClasses({ + ErroneousNonStringSourcePropertyNameParameter.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousNonStringSourcePropertyNameParameter.class, + line = 23, + message = "@SourcePropertyName can only by applied to a String parameter." + ) + } + ) + public void nonStringSourcePropertyNameParameter() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodForCollectionMapperWithTargetPropertyName.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodForCollectionMapperWithTargetPropertyName.java new file mode 100644 index 0000000000..a51a318eb6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodForCollectionMapperWithTargetPropertyName.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import java.util.Collection; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Nikola Ivačič + */ +@Mapper +public interface ConditionalMethodForCollectionMapperWithTargetPropertyName { + + ConditionalMethodForCollectionMapperWithTargetPropertyName INSTANCE + = Mappers.getMapper( ConditionalMethodForCollectionMapperWithTargetPropertyName.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotEmpty(Collection collection, @TargetPropertyName String propName) { + if ( "addresses".equalsIgnoreCase( propName ) ) { + return false; + } + return collection != null && !collection.isEmpty(); + } + + @Condition + default boolean isNotBlank(String value, @TargetPropertyName String propName) { + if ( propName.equalsIgnoreCase( "lastName" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithAllExceptTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithAllExceptTarget.java new file mode 100644 index 0000000000..1d0dd3fa51 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithAllExceptTarget.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + */ +@Mapper +public interface ConditionalMethodInMapperWithAllExceptTarget { + + ConditionalMethodInMapperWithAllExceptTarget INSTANCE + = Mappers.getMapper( ConditionalMethodInMapperWithAllExceptTarget.class ); + + class PresenceUtils { + Set visited = new LinkedHashSet<>(); + Set visitedSources = new LinkedHashSet<>(); + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtils utils); + + @Condition + default boolean isNotBlank(String value, + DomainModel source, + @TargetPropertyName String propName, + @Context PresenceUtils utils) { + utils.visited.add( propName ); + utils.visitedSources.add( source.getClass().getSimpleName() ); + if ( propName.equalsIgnoreCase( "firstName" ) ) { + return true; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithAllOptions.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithAllOptions.java new file mode 100644 index 0000000000..d3ccb9ba2e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithAllOptions.java @@ -0,0 +1,62 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.SourcePropertyName; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + */ +@Mapper +public interface ConditionalMethodInMapperWithAllOptions { + + ConditionalMethodInMapperWithAllOptions INSTANCE + = Mappers.getMapper( ConditionalMethodInMapperWithAllOptions.class ); + + class PresenceUtils { + Set visitedSourceNames = new LinkedHashSet<>(); + Set visitedTargetNames = new LinkedHashSet<>(); + Set visitedSources = new LinkedHashSet<>(); + Set visitedTargets = new LinkedHashSet<>(); + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + void map(EmployeeDto employeeDto, + @MappingTarget Employee employee, + @Context PresenceUtils utils); + + @Condition + default boolean isNotBlank(String value, + DomainModel source, + @MappingTarget DomainModel target, + @SourcePropertyName String sourcePropName, + @TargetPropertyName String targetPropName, + @Context PresenceUtils utils) { + utils.visitedSourceNames.add( sourcePropName ); + utils.visitedTargetNames.add( targetPropName ); + utils.visitedSources.add( source.getClass().getSimpleName() ); + utils.visitedTargets.add( target.getClass().getSimpleName() ); + if ( targetPropName.equalsIgnoreCase( "lastName" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithTargetPropertyName.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithTargetPropertyName.java new file mode 100644 index 0000000000..d5dc378f32 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInMapperWithTargetPropertyName.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + */ +@Mapper +public interface ConditionalMethodInMapperWithTargetPropertyName { + + ConditionalMethodInMapperWithTargetPropertyName INSTANCE + = Mappers.getMapper( ConditionalMethodInMapperWithTargetPropertyName.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value, @TargetPropertyName String propName) { + if ( propName.equalsIgnoreCase( "lastName" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInUsesMapperWithTargetPropertyName.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInUsesMapperWithTargetPropertyName.java new file mode 100644 index 0000000000..381b99d4f4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodInUsesMapperWithTargetPropertyName.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + */ +@Mapper(uses = ConditionalMethodInUsesMapperWithTargetPropertyName.PresenceUtils.class) +public interface ConditionalMethodInUsesMapperWithTargetPropertyName { + + ConditionalMethodInUsesMapperWithTargetPropertyName INSTANCE + = Mappers.getMapper( ConditionalMethodInUsesMapperWithTargetPropertyName.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + class PresenceUtils { + + @Condition + public boolean isNotBlank(String value, @TargetPropertyName String propName) { + if ( propName.equalsIgnoreCase( "lastName" ) ) { + return false; + } + return value != null && !value.trim().isEmpty(); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodWithTargetPropertyNameInContextMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodWithTargetPropertyNameInContextMapper.java new file mode 100644 index 0000000000..85704b0601 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ConditionalMethodWithTargetPropertyNameInContextMapper.java @@ -0,0 +1,106 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import java.util.Deque; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Condition; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.TargetType; +import org.mapstruct.ap.test.conditional.propertyname.Address; +import org.mapstruct.ap.test.conditional.propertyname.AddressDto; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Nikola Ivačič + */ +@Mapper +public interface ConditionalMethodWithTargetPropertyNameInContextMapper { + + ConditionalMethodWithTargetPropertyNameInContextMapper INSTANCE + = Mappers.getMapper( ConditionalMethodWithTargetPropertyNameInContextMapper.class ); + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtils utils); + + Address map(AddressDto addressDto, @Context PresenceUtils utils); + + class PresenceUtils { + Set visited = new LinkedHashSet<>(); + + @Condition + public boolean isNotBlank(String value, @TargetPropertyName String propName) { + visited.add( propName ); + return value != null && !value.trim().isEmpty(); + } + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtilsAllProps utils); + + Address map(AddressDto addressDto, @Context PresenceUtilsAllProps utils); + + class PresenceUtilsAllProps { + Set visited = new LinkedHashSet<>(); + + @Condition + public boolean collect(@TargetPropertyName String propName) { + visited.add( propName ); + return true; + } + } + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee, @Context PresenceUtilsAllPropsWithSource utils); + + Address map(AddressDto addressDto, @Context PresenceUtilsAllPropsWithSource utils); + + @BeforeMapping + default void before(DomainModel source, @Context PresenceUtilsAllPropsWithSource utils) { + String lastProp = utils.visitedSegments.peekLast(); + if ( lastProp != null && source != null ) { + utils.path.offerLast( lastProp ); + } + } + + @AfterMapping + default void after(@TargetType Class targetClass, @Context PresenceUtilsAllPropsWithSource utils) { + // intermediate method for collection mapping must not change the path + if ( targetClass != List.class ) { + utils.path.pollLast(); + } + } + + class PresenceUtilsAllPropsWithSource { + Deque visitedSegments = new LinkedList<>(); + Deque visited = new LinkedList<>(); + Deque path = new LinkedList<>(); + + @Condition + public boolean collect(@TargetPropertyName String propName) { + visitedSegments.offerLast( propName ); + path.offerLast( propName ); + visited.offerLast( String.join( ".", path ) ); + path.pollLast(); + return true; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ErroneousNonStringTargetPropertyNameParameter.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ErroneousNonStringTargetPropertyNameParameter.java new file mode 100644 index 0000000000..d56277abf4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/ErroneousNonStringTargetPropertyNameParameter.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.TargetPropertyName; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; + +@Mapper +public interface ErroneousNonStringTargetPropertyNameParameter { + + @Mapping(target = "country", source = "originCountry") + @Mapping(target = "addresses", source = "originAddresses") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value, @TargetPropertyName int propName) { + return value != null && !value.trim().isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/TargetPropertyNameTest.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/TargetPropertyNameTest.java new file mode 100644 index 0000000000..bb90c0b069 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/propertyname/targetpropertyname/TargetPropertyNameTest.java @@ -0,0 +1,311 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.propertyname.targetpropertyname; + +import java.util.Collections; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.conditional.propertyname.Address; +import org.mapstruct.ap.test.conditional.propertyname.AddressDto; +import org.mapstruct.ap.test.conditional.propertyname.DomainModel; +import org.mapstruct.ap.test.conditional.propertyname.Employee; +import org.mapstruct.ap.test.conditional.propertyname.EmployeeDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + * @author Nikola Ivačič + */ +@IssueKey("2051") +@WithClasses({ + Address.class, + AddressDto.class, + Employee.class, + EmployeeDto.class, + DomainModel.class +}) +public class TargetPropertyNameTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapperWithTargetPropertyName.class + }) + public void conditionalMethodInMapperWithTargetPropertyName() { + ConditionalMethodInMapperWithTargetPropertyName mapper + = ConditionalMethodInMapperWithTargetPropertyName.INSTANCE; + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodForCollectionMapperWithTargetPropertyName.class + }) + public void conditionalMethodForCollectionMapperWithTargetPropertyName() { + ConditionalMethodForCollectionMapperWithTargetPropertyName mapper + = ConditionalMethodForCollectionMapperWithTargetPropertyName.INSTANCE; + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInUsesMapperWithTargetPropertyName.class + }) + public void conditionalMethodInUsesMapperWithTargetPropertyName() { + ConditionalMethodInUsesMapperWithTargetPropertyName mapper + = ConditionalMethodInUsesMapperWithTargetPropertyName.INSTANCE; + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapperWithAllOptions.class + }) + public void conditionalMethodInMapperWithAllOptions() { + ConditionalMethodInMapperWithAllOptions mapper + = ConditionalMethodInMapperWithAllOptions.INSTANCE; + + ConditionalMethodInMapperWithAllOptions.PresenceUtils utils = + new ConditionalMethodInMapperWithAllOptions.PresenceUtils(); + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = new Employee(); + mapper.map( employeeDto, employee, utils ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getFirstName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( utils.visitedSourceNames ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "originCountry" ); + assertThat( utils.visitedTargetNames ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "country" ); + assertThat( utils.visitedSources ).containsExactly( "EmployeeDto" ); + assertThat( utils.visitedTargets ).containsExactly( "Employee" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodInMapperWithAllExceptTarget.class + }) + public void conditionalMethodInMapperWithAllExceptTarget() { + ConditionalMethodInMapperWithAllExceptTarget mapper + = ConditionalMethodInMapperWithAllExceptTarget.INSTANCE; + + ConditionalMethodInMapperWithAllExceptTarget.PresenceUtils utils = + new ConditionalMethodInMapperWithAllExceptTarget.PresenceUtils(); + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setFirstName( " " ); + employeeDto.setLastName( "Testirovich" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto, utils ); + assertThat( employee.getLastName() ).isEqualTo( "Testirovich" ); + assertThat( employee.getFirstName() ).isEqualTo( " " ); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( utils.visited ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "country", "street" ); + assertThat( utils.visitedSources ).containsExactlyInAnyOrder( "EmployeeDto", "AddressDto" ); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithTargetPropertyNameInContextMapper.class + }) + public void conditionalMethodWithTargetPropertyNameInUsesContextMapper() { + ConditionalMethodWithTargetPropertyNameInContextMapper mapper + = ConditionalMethodWithTargetPropertyNameInContextMapper.INSTANCE; + + ConditionalMethodWithTargetPropertyNameInContextMapper.PresenceUtils utils = + new ConditionalMethodWithTargetPropertyNameInContextMapper.PresenceUtils(); + + EmployeeDto employeeDto = new EmployeeDto(); + employeeDto.setLastName( " " ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + Employee employee = mapper.map( employeeDto, utils ); + assertThat( employee.getLastName() ).isNull(); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( utils.visited ) + .containsExactlyInAnyOrder( "firstName", "lastName", "title", "country", "street" ); + + ConditionalMethodWithTargetPropertyNameInContextMapper.PresenceUtilsAllProps allPropsUtils = + new ConditionalMethodWithTargetPropertyNameInContextMapper.PresenceUtilsAllProps(); + + employeeDto = new EmployeeDto(); + employeeDto.setLastName( "Tester" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + employee = mapper.map( employeeDto, allPropsUtils ); + assertThat( employee.getLastName() ).isEqualTo( "Tester" ); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 6" ); + assertThat( allPropsUtils.visited ) + .containsExactlyInAnyOrder( + "firstName", + "lastName", + "title", + "country", + "active", + "age", + "boss", + "primaryAddress", + "addresses", + "street" + ); + + ConditionalMethodWithTargetPropertyNameInContextMapper.PresenceUtilsAllPropsWithSource allPropsUtilsWithSource = + new ConditionalMethodWithTargetPropertyNameInContextMapper.PresenceUtilsAllPropsWithSource(); + + EmployeeDto bossEmployeeDto = new EmployeeDto(); + bossEmployeeDto.setLastName( "Boss Tester" ); + bossEmployeeDto.setOriginCountry( "US" ); + bossEmployeeDto.setOriginAddresses( Collections.singletonList( new AddressDto( + "Testing St. 10" ) ) ); + + employeeDto = new EmployeeDto(); + employeeDto.setLastName( "Tester" ); + employeeDto.setOriginCountry( "US" ); + employeeDto.setBoss( bossEmployeeDto ); + employeeDto.setOriginAddresses( + Collections.singletonList( new AddressDto( "Testing St. 6" ) ) + ); + + employee = mapper.map( employeeDto, allPropsUtilsWithSource ); + assertThat( employee.getLastName() ).isEqualTo( "Tester" ); + assertThat( employee.getCountry() ).isEqualTo( "US" ); + assertThat( employee.getAddresses() ).isNotEmpty(); + assertThat( employee.getAddresses().get( 0 ).getStreet() ).isEqualTo( "Testing St. 6" ); + assertThat( employee.getBoss() ).isNotNull(); + assertThat( employee.getBoss().getCountry() ).isEqualTo( "US" ); + assertThat( employee.getBoss().getLastName() ).isEqualTo( "Boss Tester" ); + assertThat( employee.getBoss().getAddresses() ) + .extracting( Address::getStreet ) + .containsExactly( "Testing St. 10" ); + assertThat( allPropsUtilsWithSource.visited ) + .containsExactly( + "country", + "addresses", + "addresses.street", + "firstName", + "lastName", + "title", + "active", + "age", + "boss", + "boss.country", + "boss.addresses", + "boss.addresses.street", + "boss.firstName", + "boss.lastName", + "boss.title", + "boss.active", + "boss.age", + "boss.boss", + "boss.primaryAddress", + "primaryAddress" + ); + } + + @IssueKey("2863") + @ProcessorTest + @WithClasses({ + ErroneousNonStringTargetPropertyNameParameter.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousNonStringTargetPropertyNameParameter.class, + line = 23, + message = "@TargetPropertyName can only by applied to a String parameter." + ) + } + ) + public void nonStringTargetPropertyNameParameter() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithClassQualifiersMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithClassQualifiersMapper.java new file mode 100644 index 0000000000..7cbef82a5a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithClassQualifiersMapper.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.qualifier; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.Qualifier; +import org.mapstruct.ap.test.conditional.Employee; +import org.mapstruct.ap.test.conditional.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = ConditionalMethodWithClassQualifiersMapper.StaticUtil.class) +public interface ConditionalMethodWithClassQualifiersMapper { + + ConditionalMethodWithClassQualifiersMapper INSTANCE = + Mappers.getMapper( ConditionalMethodWithClassQualifiersMapper.class ); + + @Mapping(target = "ssid", source = "uniqueIdNumber", + conditionQualifiedBy = UtilConditions.class, conditionQualifiedByName = "american") + @Mapping(target = "nin", source = "uniqueIdNumber", + conditionQualifiedBy = UtilConditions.class, conditionQualifiedByName = "british") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + @UtilConditions + interface StaticUtil { + + @Condition + @Named("american") + static boolean isAmericanCitizen(EmployeeDto employerDto) { + return "US".equals( employerDto.getCountry() ); + } + + @Condition + @Named("british") + static boolean isBritishCitizen(EmployeeDto employeeDto) { + return "UK".equals( employeeDto.getCountry() ); + } + } + + @Qualifier + @Target(ElementType.TYPE) + @Retention(RetentionPolicy.CLASS) + @interface UtilConditions { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithSourceParameterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithSourceParameterMapper.java new file mode 100644 index 0000000000..c04269d574 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithSourceParameterMapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.qualifier; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.ap.test.conditional.Employee; +import org.mapstruct.ap.test.conditional.EmployeeDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = ConditionalMethodWithSourceParameterMapper.StaticUtil.class) +public interface ConditionalMethodWithSourceParameterMapper { + + ConditionalMethodWithSourceParameterMapper INSTANCE = + Mappers.getMapper( ConditionalMethodWithSourceParameterMapper.class ); + + @Mapping(target = "ssid", source = "uniqueIdNumber", conditionQualifiedByName = "isAmericanCitizen") + @Mapping(target = "nin", source = "uniqueIdNumber", conditionQualifiedByName = "isBritishCitizen") + Employee map(EmployeeDto employee); + + @Condition + default boolean isNotBlank(String value) { + return value != null && !value.trim().isEmpty(); + } + + @Condition + @Named("isAmericanCitizen") + default boolean isAmericanCitizen(EmployeeDto employerDto) { + return "US".equals( employerDto.getCountry() ); + } + + interface StaticUtil { + + @Condition + @Named("isBritishCitizen") + static boolean isBritishCitizen(EmployeeDto employeeDto) { + return "UK".equals( employeeDto.getCountry() ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithSourceToTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithSourceToTargetMapper.java new file mode 100644 index 0000000000..6577a6fd95 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalMethodWithSourceToTargetMapper.java @@ -0,0 +1,132 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.qualifier; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.SourceParameterCondition; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConditionalMethodWithSourceToTargetMapper { + + ConditionalMethodWithSourceToTargetMapper INSTANCE = + Mappers.getMapper( ConditionalMethodWithSourceToTargetMapper.class ); + + @Mapping(source = "orderDTO", target = "customer", conditionQualifiedByName = "mapCustomerFromOrder") + Order convertToOrder(OrderDTO orderDTO); + + @Mapping(source = "customerName", target = "name") + @Mapping(source = "orderDTO", target = "address", conditionQualifiedByName = "mapAddressFromOrder") + Customer convertToCustomer(OrderDTO orderDTO); + + Address convertToAddress(OrderDTO orderDTO); + + @SourceParameterCondition + @Named("mapCustomerFromOrder") + default boolean mapCustomerFromOrder(OrderDTO orderDTO) { + return orderDTO != null && ( orderDTO.getCustomerName() != null || mapAddressFromOrder( orderDTO ) ); + } + + @SourceParameterCondition + @Named("mapAddressFromOrder") + default boolean mapAddressFromOrder(OrderDTO orderDTO) { + return orderDTO != null && ( orderDTO.getLine1() != null || orderDTO.getLine2() != null ); + } + + class OrderDTO { + + private String customerName; + private String line1; + private String line2; + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } + + } + + class Order { + + private Customer customer; + + public Customer getCustomer() { + return customer; + } + + public void setCustomer(Customer customer) { + this.customer = customer; + } + } + + class Customer { + private String name; + private Address address; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + } + + class Address { + + private String line1; + private String line2; + + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalQualifierTest.java b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalQualifierTest.java new file mode 100644 index 0000000000..69c9a048cd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conditional/qualifier/ConditionalQualifierTest.java @@ -0,0 +1,126 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conditional.qualifier; + +import org.mapstruct.ap.test.conditional.Employee; +import org.mapstruct.ap.test.conditional.EmployeeDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2051") +@WithClasses({ + Employee.class, + EmployeeDto.class +}) +public class ConditionalQualifierTest { + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithSourceParameterMapper.class + }) + public void conditionalMethodWithSourceParameter() { + ConditionalMethodWithSourceParameterMapper mapper = ConditionalMethodWithSourceParameterMapper.INSTANCE; + + EmployeeDto dto = new EmployeeDto(); + dto.setName( "Tester" ); + dto.setUniqueIdNumber( "SSID-001" ); + dto.setCountry( null ); + + Employee employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isNull(); + + dto.setCountry( "UK" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isEqualTo( "SSID-001" ); + assertThat( employee.getSsid() ).isNull(); + + dto.setCountry( "US" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isEqualTo( "SSID-001" ); + + dto.setCountry( "CH" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithClassQualifiersMapper.class + }) + public void conditionalClassQualifiers() { + ConditionalMethodWithClassQualifiersMapper mapper = ConditionalMethodWithClassQualifiersMapper.INSTANCE; + + EmployeeDto dto = new EmployeeDto(); + dto.setName( "Tester" ); + dto.setUniqueIdNumber( "SSID-001" ); + dto.setCountry( null ); + + Employee employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isNull(); + + dto.setCountry( "UK" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isEqualTo( "SSID-001" ); + assertThat( employee.getSsid() ).isNull(); + + dto.setCountry( "US" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isEqualTo( "SSID-001" ); + + dto.setCountry( "CH" ); + employee = mapper.map( dto ); + assertThat( employee.getNin() ).isNull(); + assertThat( employee.getSsid() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + ConditionalMethodWithSourceToTargetMapper.class + }) + @IssueKey("2666") + public void conditionalQualifiersForSourceToTarget() { + ConditionalMethodWithSourceToTargetMapper mapper = ConditionalMethodWithSourceToTargetMapper.INSTANCE; + + ConditionalMethodWithSourceToTargetMapper.OrderDTO orderDto = + new ConditionalMethodWithSourceToTargetMapper.OrderDTO(); + + ConditionalMethodWithSourceToTargetMapper.Order order = mapper.convertToOrder( orderDto ); + assertThat( order ).isNotNull(); + assertThat( order.getCustomer() ).isNull(); + + orderDto = new ConditionalMethodWithSourceToTargetMapper.OrderDTO(); + orderDto.setCustomerName( "Tester" ); + order = mapper.convertToOrder( orderDto ); + + assertThat( order ).isNotNull(); + assertThat( order.getCustomer() ).isNotNull(); + assertThat( order.getCustomer().getName() ).isEqualTo( "Tester" ); + assertThat( order.getCustomer().getAddress() ).isNull(); + + orderDto = new ConditionalMethodWithSourceToTargetMapper.OrderDTO(); + orderDto.setLine1( "Line 1" ); + order = mapper.convertToOrder( orderDto ); + + assertThat( order ).isNotNull(); + assertThat( order.getCustomer() ).isNotNull(); + assertThat( order.getCustomer().getName() ).isNull(); + assertThat( order.getCustomer().getAddress() ).isNotNull(); + assertThat( order.getCustomer().getAddress().getLine1() ).isEqualTo( "Line 1" ); + assertThat( order.getCustomer().getAddress().getLine2() ).isNull(); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/ConstructorProperties.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/ConstructorProperties.java new file mode 100644 index 0000000000..affbded7ff --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/ConstructorProperties.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Filip Hrisafov + */ +@Documented +@Target(ElementType.CONSTRUCTOR) +@Retention(RetentionPolicy.SOURCE) +public @interface ConstructorProperties { + + String[] value(); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/Default.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/Default.java new file mode 100644 index 0000000000..96b30c02ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/Default.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Filip Hrisafov + */ +@Documented +@Target(ElementType.CONSTRUCTOR) +@Retention(RetentionPolicy.SOURCE) +public @interface Default { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/Person.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/Person.java new file mode 100644 index 0000000000..8fc9e7ce30 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/Person.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class Person { + + private final String name; + private final int age; + private final String job; + private final String city; + private final String address; + private final List children; + + public Person(String name, int age, String job, String city, String address, + List children) { + this.name = name; + this.age = age; + this.job = job; + this.city = city; + this.address = address; + this.children = children; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public String getJob() { + return job; + } + + public String getCity() { + return city; + } + + public String getAddress() { + return address; + } + + public List getChildren() { + return children; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/PersonDto.java new file mode 100644 index 0000000000..0b2cba09cd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/PersonDto.java @@ -0,0 +1,69 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class PersonDto { + + private String name; + private int age; + private String job; + private String city; + private String address; + private List children; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getJob() { + return job; + } + + public void setJob(String job) { + this.job = job; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/PersonWithConstructorProperties.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/PersonWithConstructorProperties.java new file mode 100644 index 0000000000..8419442cf1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/PersonWithConstructorProperties.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.constructorproperties; + +import java.util.List; + +import org.mapstruct.ap.test.constructor.ConstructorProperties; + +/** + * @author Filip Hrisafov + */ +public class PersonWithConstructorProperties { + + private final String name; + private final int age; + private final String job; + private final String city; + private final String address; + private final List children; + + @ConstructorProperties({"name", "age", "job", "city", "address", "children"}) + public PersonWithConstructorProperties(String var1, int var2, String var3, String var4, String var5, + List var6) { + this.name = var1; + this.age = var2; + this.job = var3; + this.city = var4; + this.address = var5; + this.children = var6; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + + public String getJob() { + return job; + } + + public String getCity() { + return city; + } + + public String getAddress() { + return address; + } + + public List getChildren() { + return children; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/SimpleConstructorPropertiesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/SimpleConstructorPropertiesMapper.java new file mode 100644 index 0000000000..3d32d8b31c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/SimpleConstructorPropertiesMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.constructorproperties; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleConstructorPropertiesMapper { + + SimpleConstructorPropertiesMapper INSTANCE = Mappers.getMapper( SimpleConstructorPropertiesMapper.class ); + + PersonWithConstructorProperties map(PersonDto dto); + + @Mapping(target = "age", constant = "25") + @Mapping(target = "job", constant = "Software Developer") + PersonWithConstructorProperties mapWithConstants(PersonDto dto); + + @Mapping(target = "age", expression = "java(25 - 5)") + @Mapping(target = "job", expression = "java(\"Software Developer\".toLowerCase())") + PersonWithConstructorProperties mapWithExpression(PersonDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/SimpleConstructorPropertiesTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/SimpleConstructorPropertiesTest.java new file mode 100644 index 0000000000..3e26b442ee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/constructorproperties/SimpleConstructorPropertiesTest.java @@ -0,0 +1,87 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.constructorproperties; + +import java.util.Arrays; + +import org.mapstruct.ap.test.constructor.ConstructorProperties; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + ConstructorProperties.class, + PersonWithConstructorProperties.class, + PersonDto.class, + SimpleConstructorPropertiesMapper.class +}) +public class SimpleConstructorPropertiesTest { + + @ProcessorTest + public void mapDefault() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonWithConstructorProperties target = SimpleConstructorPropertiesMapper.INSTANCE.map( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 30 ); + assertThat( target.getJob() ).isEqualTo( "Software Engineer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } + + @ProcessorTest + public void mapWithConstants() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonWithConstructorProperties target = SimpleConstructorPropertiesMapper.INSTANCE.mapWithConstants( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 25 ); + assertThat( target.getJob() ).isEqualTo( "Software Developer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } + + @ProcessorTest + public void mapWithExpressions() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonWithConstructorProperties target = SimpleConstructorPropertiesMapper.INSTANCE.mapWithExpression( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 20 ); + assertThat( target.getJob() ).isEqualTo( "software developer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/PersonWithDefaultAnnotatedConstructor.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/PersonWithDefaultAnnotatedConstructor.java new file mode 100644 index 0000000000..190ab818ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/PersonWithDefaultAnnotatedConstructor.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.defaultannotated; + +import org.mapstruct.ap.test.constructor.Default; + +/** + * @author Filip Hrisafov + */ +public class PersonWithDefaultAnnotatedConstructor { + + private final String name; + private final int age; + + public PersonWithDefaultAnnotatedConstructor(String name) { + this( name, -1 ); + } + + @Default + public PersonWithDefaultAnnotatedConstructor(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/SimpleDefaultAnnotatedConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/SimpleDefaultAnnotatedConstructorMapper.java new file mode 100644 index 0000000000..6934c34fe4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/SimpleDefaultAnnotatedConstructorMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.defaultannotated; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleDefaultAnnotatedConstructorMapper { + + SimpleDefaultAnnotatedConstructorMapper INSTANCE = + Mappers.getMapper( SimpleDefaultAnnotatedConstructorMapper.class ); + + PersonWithDefaultAnnotatedConstructor map(PersonDto dto); + + @Mapping(target = "age", constant = "25") + PersonWithDefaultAnnotatedConstructor mapWithConstants(PersonDto dto); + + @Mapping(target = "age", expression = "java(25 - 5)") + PersonWithDefaultAnnotatedConstructor mapWithExpression(PersonDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/SimpleDefaultAnnotatedConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/SimpleDefaultAnnotatedConstructorTest.java new file mode 100644 index 0000000000..25f4fb8b1d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/defaultannotated/SimpleDefaultAnnotatedConstructorTest.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.defaultannotated; + +import java.util.Arrays; + +import org.mapstruct.ap.test.constructor.Default; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Default.class, + PersonWithDefaultAnnotatedConstructor.class, + PersonDto.class, + SimpleDefaultAnnotatedConstructorMapper.class +}) +public class SimpleDefaultAnnotatedConstructorTest { + + @ProcessorTest + public void mapDefault() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonWithDefaultAnnotatedConstructor target = SimpleDefaultAnnotatedConstructorMapper.INSTANCE.map( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 30 ); + } + + @ProcessorTest + public void mapWithConstants() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonWithDefaultAnnotatedConstructor target = + SimpleDefaultAnnotatedConstructorMapper.INSTANCE.mapWithConstants( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 25 ); + } + + @ProcessorTest + public void mapWithExpressions() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonWithDefaultAnnotatedConstructor target = + SimpleDefaultAnnotatedConstructorMapper.INSTANCE.mapWithExpression( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 20 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousAmbiguousConstructorsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousAmbiguousConstructorsMapper.java new file mode 100644 index 0000000000..afa37ea77b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousAmbiguousConstructorsMapper.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.constructor.PersonDto; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousAmbiguousConstructorsMapper { + + PersonWithMultipleConstructors map(PersonDto dto); + + class PersonWithMultipleConstructors { + + private final String name; + private final int age; + + public PersonWithMultipleConstructors(String name) { + this( name, -1 ); + } + + public PersonWithMultipleConstructors(String name, int age) { + this.name = name; + this.age = age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousConstructorPropertiesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousConstructorPropertiesMapper.java new file mode 100644 index 0000000000..930db7f8a4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousConstructorPropertiesMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.constructor.ConstructorProperties; +import org.mapstruct.ap.test.constructor.PersonDto; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousConstructorPropertiesMapper { + + PersonWithIncorrectConstructorProperties map(PersonDto dto); + + class PersonWithIncorrectConstructorProperties { + + private final String name; + private final int age; + + @ConstructorProperties({ "name" }) + public PersonWithIncorrectConstructorProperties(String name, int age) { + this.name = name; + this.age = age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousConstructorTest.java new file mode 100644 index 0000000000..5a8483f23b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/erroneous/ErroneousConstructorTest.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.erroneous; + +import org.mapstruct.ap.test.constructor.ConstructorProperties; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * @author Filip Hrisafov + */ +public class ErroneousConstructorTest { + + @ProcessorTest + @WithClasses({ + ErroneousAmbiguousConstructorsMapper.class, + PersonDto.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { + @Diagnostic( + type = ErroneousAmbiguousConstructorsMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Ambiguous constructors found for creating org.mapstruct.ap.test.constructor.erroneous" + + ".ErroneousAmbiguousConstructorsMapper.PersonWithMultipleConstructors: " + + "PersonWithMultipleConstructors(java.lang.String), " + + "PersonWithMultipleConstructors(java.lang.String, int). Either declare parameterless constructor " + + "or annotate the default constructor with an annotation named @Default." + ) + }) + public void shouldUseMultipleConstructors() { + } + + @ProcessorTest + @WithClasses({ + ConstructorProperties.class, + ErroneousConstructorPropertiesMapper.class, + PersonDto.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { + @Diagnostic( + type = ErroneousConstructorPropertiesMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 18, + message = "Incorrect @ConstructorProperties for org.mapstruct.ap.test.constructor.erroneous" + + ".ErroneousConstructorPropertiesMapper.PersonWithIncorrectConstructorProperties. The size of the " + + "@ConstructorProperties does not match the number of constructor parameters") + }) + public void shouldNotCompileIfConstructorPropertiesDoesNotMatch() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/manysourcearguments/ManySourceArgumentsConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/manysourcearguments/ManySourceArgumentsConstructorMapper.java new file mode 100644 index 0000000000..dfa3b4be5c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/manysourcearguments/ManySourceArgumentsConstructorMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.manysourcearguments; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.constructor.Person; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface ManySourceArgumentsConstructorMapper { + + ManySourceArgumentsConstructorMapper INSTANCE = Mappers.getMapper( ManySourceArgumentsConstructorMapper.class ); + + @Mapping(target = "name", defaultValue = "Tester") + @Mapping(target = "city", defaultExpression = "java(\"Zurich\")") + Person map(String name, String city); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/manysourcearguments/ManySourceArgumentsConstructorMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/manysourcearguments/ManySourceArgumentsConstructorMappingTest.java new file mode 100644 index 0000000000..7611cc2364 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/manysourcearguments/ManySourceArgumentsConstructorMappingTest.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.manysourcearguments; + +import org.mapstruct.ap.test.constructor.Person; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses( { + ManySourceArgumentsConstructorMapper.class, + Person.class, +} ) +public class ManySourceArgumentsConstructorMappingTest { + + @ProcessorTest + public void shouldCorrectlyUseDefaultValueForSourceParameters() { + Person person = ManySourceArgumentsConstructorMapper.INSTANCE.map( null, "Test Valley" ); + + assertThat( person ).isNotNull(); + assertThat( person.getName() ).isEqualTo( "Tester" ); + assertThat( person.getCity() ).isEqualTo( "Test Valley" ); + + person = ManySourceArgumentsConstructorMapper.INSTANCE.map( "Other Tester", null ); + + assertThat( person ).isNotNull(); + assertThat( person.getName() ).isEqualTo( "Other Tester" ); + assertThat( person.getCity() ).isEqualTo( "Zurich" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/ConstructorMixedWithSettersMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/ConstructorMixedWithSettersMapper.java new file mode 100644 index 0000000000..02a6d9af64 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/ConstructorMixedWithSettersMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.mixed; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ConstructorMixedWithSettersMapper { + + ConstructorMixedWithSettersMapper INSTANCE = Mappers.getMapper( ConstructorMixedWithSettersMapper.class ); + + PersonMixed map(PersonDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/ConstructorMixedWithSettersTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/ConstructorMixedWithSettersTest.java new file mode 100644 index 0000000000..dde9b798f4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/ConstructorMixedWithSettersTest.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.mixed; + +import java.util.Arrays; + +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + PersonMixed.class, + PersonDto.class, + ConstructorMixedWithSettersMapper.class +}) +public class ConstructorMixedWithSettersTest { + + @ProcessorTest + public void mapDefault() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + PersonMixed target = ConstructorMixedWithSettersMapper.INSTANCE.map( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 30 ); + assertThat( target.getJob() ).isEqualTo( "Software Engineer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/PersonMixed.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/PersonMixed.java new file mode 100644 index 0000000000..deb79e84fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/mixed/PersonMixed.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.mixed; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class PersonMixed { + + private final String name; + private final int age; + private final String job; + private String city; + private String address; + private List children; + + public PersonMixed(String name, int age, String job) { + this.name = name; + this.age = age; + this.job = job; + } + + public String getName() { + return name; + } + + public void setName(String name) { + throw new RuntimeException( "Method is here only to verify that MapStruct won't use it" ); + } + + public int getAge() { + return age; + } + + public String getJob() { + return job; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntry.java new file mode 100644 index 0000000000..02a82ba8d0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntry.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Chart; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public interface ArtistToChartEntry { + + ArtistToChartEntry MAPPER = Mappers.getMapper( ArtistToChartEntry.class ); + + @Mappings({ + @Mapping(target = "chartName", source = "chart.name"), + @Mapping(target = "songTitle", source = "song.title"), + @Mapping(target = "artistName", source = "song.artist.name"), + @Mapping(target = "recordedAt", source = "song.artist.label.studio.name"), + @Mapping(target = "city", source = "song.artist.label.studio.city"), + @Mapping(target = "position", source = "position") + }) + ChartEntry map(Chart chart, Song song, Integer position); + + @Mappings({ + @Mapping(target = "chartName", ignore = true), + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistName", source = "artist.name"), + @Mapping(target = "recordedAt", source = "artist.label.studio.name"), + @Mapping(target = "city", source = "artist.label.studio.city"), + @Mapping(target = "position", ignore = true) + }) + ChartEntry map(Song song); + + @Mappings({ + @Mapping(target = "chartName", source = "name"), + @Mapping(target = "songTitle", ignore = true), + @Mapping(target = "artistName", ignore = true), + @Mapping(target = "recordedAt", ignore = true), + @Mapping(target = "city", ignore = true), + @Mapping(target = "position", ignore = true) + }) + ChartEntry map(Chart name); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryComposedReverse.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryComposedReverse.java new file mode 100644 index 0000000000..7fd9fbdb54 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryComposedReverse.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryComposed; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryLabel; +import org.mapstruct.ap.test.constructor.nestedsource.source.Label; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public abstract class ArtistToChartEntryComposedReverse { + + public static final ArtistToChartEntryComposedReverse MAPPER = + Mappers.getMapper( ArtistToChartEntryComposedReverse.class ); + + @Mappings({ + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistName", source = "artist.name"), + @Mapping(target = "label", source = "artist.label"), + @Mapping(target = "position", ignore = true), + @Mapping(target = "chartName", ignore = true ) + }) + abstract ChartEntryComposed mapForward(Song song); + + @Mappings({ + @Mapping(target = "name", source = "name"), + @Mapping(target = "recordedAt", source = "studio.name"), + @Mapping(target = "city", source = "studio.city") + }) + abstract ChartEntryLabel mapForward(Label label); + + @InheritInverseConfiguration + @Mapping(target = "positions", ignore = true) + abstract Song mapReverse(ChartEntryComposed ce); + + @InheritInverseConfiguration + abstract Label mapReverse(ChartEntryLabel label); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryConfig.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryConfig.java new file mode 100644 index 0000000000..c1d0d05228 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryConfig.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.constructor.nestedsource._target.BaseChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; + +/** + * + * @author Sjaak Derksen + */ +@MapperConfig( unmappedTargetPolicy = ReportingPolicy.ERROR ) +public interface ArtistToChartEntryConfig { + + @Mappings({ + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistName", source = "artist.name"), + @Mapping(target = "chartName", ignore = true ) + }) + BaseChartEntry mapForwardConfig( Song song ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryReverse.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryReverse.java new file mode 100644 index 0000000000..193d4ea6ec --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryReverse.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public abstract class ArtistToChartEntryReverse { + + public static final ArtistToChartEntryReverse MAPPER = Mappers.getMapper( ArtistToChartEntryReverse.class ); + + @Mappings({ + + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistName", source = "artist.name"), + @Mapping(target = "recordedAt", source = "artist.label.studio.name"), + @Mapping(target = "city", source = "artist.label.studio.city"), + @Mapping(target = "position", ignore = true), + @Mapping(target = "chartName", ignore = true ) + }) + abstract ChartEntry mapForward(Song song); + + @InheritInverseConfiguration + @Mapping(target = "positions", ignore = true) + abstract Song mapReverse(ChartEntry ce); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithConfigReverse.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithConfigReverse.java new file mode 100644 index 0000000000..7c21104a6b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithConfigReverse.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.InheritConfiguration; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryWithBase; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper( config = ArtistToChartEntryConfig.class ) +public abstract class ArtistToChartEntryWithConfigReverse { + + public static final ArtistToChartEntryWithConfigReverse MAPPER = + Mappers.getMapper( ArtistToChartEntryWithConfigReverse.class ); + + @InheritConfiguration + @Mappings({ + @Mapping(target = "recordedAt", source = "artist.label.studio.name"), + @Mapping(target = "city", source = "artist.label.studio.city"), + @Mapping(target = "position", ignore = true) + }) + abstract ChartEntryWithBase mapForward(Song song); + + @InheritInverseConfiguration( name = "mapForward" ) + @Mapping(target = "positions", ignore = true) + abstract Song mapReverse(ChartEntryWithBase ce); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithFactoryReverse.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithFactoryReverse.java new file mode 100644 index 0000000000..6583838673 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithFactoryReverse.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public abstract class ArtistToChartEntryWithFactoryReverse { + + public static final ArtistToChartEntryWithFactoryReverse MAPPER + = Mappers.getMapper( ArtistToChartEntryWithFactoryReverse.class ); + + @Mappings({ + + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistName", source = "artist.name"), + @Mapping(target = "recordedAt", source = "artist.label.studio.name"), + @Mapping(target = "city", source = "artist.label.studio.city"), + @Mapping(target = "position", ignore = true), + @Mapping(target = "chartName", ignore = true) + }) + abstract ChartEntry mapForward(Song song); + + @InheritInverseConfiguration + @Mapping(target = "positions", ignore = true) + abstract Song mapReverse(ChartEntry ce); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithIgnoresReverse.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithIgnoresReverse.java new file mode 100644 index 0000000000..4d1d35fbe6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithIgnoresReverse.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public abstract class ArtistToChartEntryWithIgnoresReverse { + + public static final ArtistToChartEntryWithIgnoresReverse MAPPER = + Mappers.getMapper( ArtistToChartEntryWithIgnoresReverse.class ); + + @Mappings({ + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistName", source = "artist.name"), + @Mapping(target = "recordedAt", source = "artist.label.studio.name"), + @Mapping(target = "city", source = "artist.label.studio.city"), + @Mapping(target = "position", ignore = true), + @Mapping(target = "chartName", ignore = true) + }) + abstract ChartEntry mapForward(Song song); + + @InheritInverseConfiguration + @Mappings({ + @Mapping(target = "positions", ignore = true), + @Mapping(target = "artist", ignore = true) + }) + abstract Song mapReverse(ChartEntry ce); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithMappingReverse.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithMappingReverse.java new file mode 100644 index 0000000000..b6b4cac803 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ArtistToChartEntryWithMappingReverse.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryWithMapping; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public abstract class ArtistToChartEntryWithMappingReverse { + + public static final ArtistToChartEntryWithMappingReverse MAPPER = + Mappers.getMapper( ArtistToChartEntryWithMappingReverse.class ); + + @Mappings({ + @Mapping(target = "songTitle", source = "title"), + @Mapping(target = "artistId", source = "artist.name"), + @Mapping(target = "recordedAt", source = "artist.label.studio.name"), + @Mapping(target = "city", source = "artist.label.studio.city"), + @Mapping(target = "position", ignore = true), + @Mapping(target = "chartName", ignore = true) + }) + abstract ChartEntryWithMapping mapForward(Song song); + + @InheritInverseConfiguration + @Mapping(target = "positions", ignore = true) + abstract Song mapReverse(ChartEntryWithMapping ce); + + int mapArtistToArtistId(String in) { + + if ( "The Beatles".equals( in ) ) { + return 1; + } + else { + return -1; + } + } + + String mapArtistIdToArtist(int in) { + + if ( in == 1 ) { + return "The Beatles"; + } + else { + return "Unknown"; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/NestedSourcePropertiesConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/NestedSourcePropertiesConstructorTest.java new file mode 100644 index 0000000000..653fccd118 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/NestedSourcePropertiesConstructorTest.java @@ -0,0 +1,129 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import java.util.Collections; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Artist; +import org.mapstruct.ap.test.constructor.nestedsource.source.Chart; +import org.mapstruct.ap.test.constructor.nestedsource.source.Label; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.ap.test.constructor.nestedsource.source.Studio; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@WithClasses({ Song.class, Artist.class, Chart.class, Label.class, Studio.class, ChartEntry.class }) +@IssueKey("73") +public class NestedSourcePropertiesConstructorTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ ArtistToChartEntry.class }) + public void shouldGenerateImplementationForPropertyNamesOnly() { + generatedSource.addComparisonToFixtureFor( ArtistToChartEntry.class ); + + Studio studio = new Studio( "Abbey Road", "London" ); + + Label label = new Label( "EMY", studio ); + + Artist artist = new Artist( "The Beatles", label ); + + Song song = new Song( artist, "A Hard Day's Night", Collections.emptyList() ); + + ChartEntry chartEntry = ArtistToChartEntry.MAPPER.map( song ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + } + + @ProcessorTest + @WithClasses({ ArtistToChartEntry.class }) + public void shouldGenerateImplementationForMultipleParam() { + + Studio studio = new Studio( "Abbey Road", "London" ); + + Label label = new Label( "EMY", studio ); + + Artist artist = new Artist( "The Beatles", label ); + + Song song = new Song( artist, "A Hard Day's Night", Collections.emptyList() ); + + Chart chart = new Chart( "record-sales", "Billboard", null ); + + ChartEntry chartEntry = ArtistToChartEntry.MAPPER.map( chart, song, 1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isEqualTo( "Billboard" ); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 1 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + chartEntry = ArtistToChartEntry.MAPPER.map( null, song, 10 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 10 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + chartEntry = ArtistToChartEntry.MAPPER.map( chart, null, 5 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isNull(); + assertThat( chartEntry.getChartName() ).isEqualTo( "Billboard" ); + assertThat( chartEntry.getCity() ).isNull(); + assertThat( chartEntry.getPosition() ).isEqualTo( 5 ); + assertThat( chartEntry.getRecordedAt() ).isNull(); + assertThat( chartEntry.getSongTitle() ).isNull(); + + chartEntry = ArtistToChartEntry.MAPPER.map( chart, song, null ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isEqualTo( "Billboard" ); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + } + + @ProcessorTest + @WithClasses({ ArtistToChartEntry.class }) + public void shouldPickPropertyNameOverParameterName() { + + Chart chart = new Chart( "record-sales", "Billboard", null ); + + ChartEntry chartEntry = ArtistToChartEntry.MAPPER.map( chart ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isNull(); + assertThat( chartEntry.getChartName() ).isEqualTo( "Billboard" ); + assertThat( chartEntry.getCity() ).isNull(); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isNull(); + assertThat( chartEntry.getSongTitle() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ReversingNestedSourcePropertiesConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ReversingNestedSourcePropertiesConstructorTest.java new file mode 100644 index 0000000000..73b23c5677 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/ReversingNestedSourcePropertiesConstructorTest.java @@ -0,0 +1,219 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource; + +import java.util.Collections; + +import org.mapstruct.ap.test.constructor.nestedsource._target.BaseChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryComposed; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryLabel; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryWithBase; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntryWithMapping; +import org.mapstruct.ap.test.constructor.nestedsource.source.Artist; +import org.mapstruct.ap.test.constructor.nestedsource.source.Chart; +import org.mapstruct.ap.test.constructor.nestedsource.source.Label; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.ap.test.constructor.nestedsource.source.Studio; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("73") +@WithClasses({ Song.class, Artist.class, Chart.class, Label.class, Studio.class, ChartEntry.class }) +public class ReversingNestedSourcePropertiesConstructorTest { + + @ProcessorTest + @WithClasses({ ArtistToChartEntryReverse.class }) + public void shouldGenerateNestedReverse() { + + Song song1 = prepareSong(); + + ChartEntry chartEntry = ArtistToChartEntryReverse.MAPPER.mapForward( song1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + // and now in reverse + Song song2 = ArtistToChartEntryReverse.MAPPER.mapReverse( chartEntry ); + + assertThat( song2 ).isNotNull(); + assertThat( song2.getArtist() ).isNotNull(); + assertThat( song2.getArtist().getName() ).isEqualTo( "The Beatles" ); + assertThat( song2.getArtist().getLabel() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getName() ).isNull(); + assertThat( song2.getArtist().getLabel().getStudio() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getStudio().getCity() ).isEqualTo( "London" ); + assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); + } + + @ProcessorTest + @WithClasses({ ArtistToChartEntryWithIgnoresReverse.class }) + public void shouldIgnoreEverytingBelowArtist() { + + Song song1 = prepareSong(); + + ChartEntry chartEntry = ArtistToChartEntryWithIgnoresReverse.MAPPER.mapForward( song1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + // and now in reverse + Song song2 = ArtistToChartEntryWithIgnoresReverse.MAPPER.mapReverse( chartEntry ); + + assertThat( song2 ).isNotNull(); + assertThat( song2.getArtist() ).isNull(); + } + + @ProcessorTest + @WithClasses({ ArtistToChartEntryWithFactoryReverse.class }) + public void shouldGenerateNestedReverseWithFactory() { + + Song song1 = prepareSong(); + + ChartEntry chartEntry = ArtistToChartEntryWithFactoryReverse.MAPPER.mapForward( song1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + // and now in reverse + Song song2 = ArtistToChartEntryWithFactoryReverse.MAPPER.mapReverse( chartEntry ); + + assertThat( song2 ).isNotNull(); + assertThat( song2.getArtist() ).isNotNull(); + assertThat( song2.getArtist().getName() ).isEqualTo( "The Beatles" ); + assertThat( song2.getArtist().getLabel() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getName() ).isNull(); + assertThat( song2.getArtist().getLabel().getStudio() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getStudio().getCity() ).isEqualTo( "London" ); + assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); + + } + + @ProcessorTest + @WithClasses({ ArtistToChartEntryComposedReverse.class, ChartEntryComposed.class, ChartEntryLabel.class }) + public void shouldGenerateNestedComposedReverse() { + + Song song1 = prepareSong(); + + ChartEntryComposed chartEntry = ArtistToChartEntryComposedReverse.MAPPER.mapForward( song1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getLabel().getName() ).isEqualTo( "EMY" ); + assertThat( chartEntry.getLabel().getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getLabel().getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + // and now in reverse + Song song2 = ArtistToChartEntryComposedReverse.MAPPER.mapReverse( chartEntry ); + + assertThat( song2 ).isNotNull(); + assertThat( song2.getArtist() ).isNotNull(); + assertThat( song2.getArtist().getName() ).isEqualTo( "The Beatles" ); + assertThat( song2.getArtist().getLabel() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getName() ).isEqualTo( "EMY" ); + assertThat( song2.getArtist().getLabel().getStudio() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getStudio().getCity() ).isEqualTo( "London" ); + assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); + } + + @ProcessorTest + @WithClasses({ ArtistToChartEntryWithMappingReverse.class, ChartEntryWithMapping.class }) + public void shouldGenerateNestedWithMappingReverse() { + + Song song1 = prepareSong(); + + ChartEntryWithMapping chartEntry = ArtistToChartEntryWithMappingReverse.MAPPER.mapForward( song1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistId() ).isEqualTo( 1 ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + // and now in reverse + Song song2 = ArtistToChartEntryWithMappingReverse.MAPPER.mapReverse( chartEntry ); + + assertThat( song2 ).isNotNull(); + assertThat( song2.getArtist() ).isNotNull(); + assertThat( song2.getArtist().getName() ).isEqualTo( "The Beatles" ); + assertThat( song2.getArtist().getLabel() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getName() ).isNull(); + assertThat( song2.getArtist().getLabel().getStudio() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getStudio().getCity() ).isEqualTo( "London" ); + assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); + } + + @ProcessorTest + @WithClasses({ + ArtistToChartEntryWithConfigReverse.class, + ArtistToChartEntryConfig.class, + BaseChartEntry.class, + ChartEntryWithBase.class + }) + public void shouldGenerateNestedWithConfigReverse() { + + Song song1 = prepareSong(); + + ChartEntryWithBase chartEntry = ArtistToChartEntryWithConfigReverse.MAPPER.mapForward( song1 ); + + assertThat( chartEntry ).isNotNull(); + assertThat( chartEntry.getArtistName() ).isEqualTo( "The Beatles" ); + assertThat( chartEntry.getChartName() ).isNull(); + assertThat( chartEntry.getCity() ).isEqualTo( "London" ); + assertThat( chartEntry.getPosition() ).isEqualTo( 0 ); + assertThat( chartEntry.getRecordedAt() ).isEqualTo( "Abbey Road" ); + assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); + + // and now in reverse + Song song2 = ArtistToChartEntryWithConfigReverse.MAPPER.mapReverse( chartEntry ); + + assertThat( song2 ).isNotNull(); + assertThat( song2.getArtist() ).isNotNull(); + assertThat( song2.getArtist().getName() ).isEqualTo( "The Beatles" ); + assertThat( song2.getArtist().getLabel() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getName() ).isNull(); + assertThat( song2.getArtist().getLabel().getStudio() ).isNotNull(); + assertThat( song2.getArtist().getLabel().getStudio().getCity() ).isEqualTo( "London" ); + assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); + } + + private Song prepareSong() { + Studio studio = new Studio( "Abbey Road", "London" ); + + Label label = new Label( "EMY", studio ); + + Artist artist = new Artist( "The Beatles", label ); + + return new Song( artist, "A Hard Day's Night", Collections.emptyList() ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/AdderUsageObserver.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/AdderUsageObserver.java new file mode 100644 index 0000000000..ff21870b75 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/AdderUsageObserver.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Sjaak Derksen + */ +public class AdderUsageObserver { + + private AdderUsageObserver() { + } + + private static boolean used = false; + + public static boolean isUsed() { + return used; + } + + public static void setUsed(boolean used) { + AdderUsageObserver.used = used; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/BaseChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/BaseChartEntry.java new file mode 100644 index 0000000000..7b82c77b32 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/BaseChartEntry.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Filip Hrisafov + */ +public class BaseChartEntry { + + private final String chartName; + private final String songTitle; + private final String artistName; + + public BaseChartEntry(String chartName, String songTitle, String artistName) { + this.chartName = chartName; + this.songTitle = songTitle; + this.artistName = artistName; + } + + public String getChartName() { + return chartName; + } + + public String getSongTitle() { + return songTitle; + } + + public String getArtistName() { + return artistName; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntry.java new file mode 100644 index 0000000000..36d7e95601 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntry.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Filip Hrisafov + */ +public class ChartEntry { + + private final String chartName; + private final String songTitle; + private final String artistName; + private final String recordedAt; + private final String city; + private final int position; + + public ChartEntry(String chartName, String songTitle, String artistName, String recordedAt, String city, + int position) { + this.chartName = chartName; + this.songTitle = songTitle; + this.artistName = artistName; + this.recordedAt = recordedAt; + this.city = city; + this.position = position; + } + + public String getChartName() { + return chartName; + } + + public String getSongTitle() { + return songTitle; + } + + public String getArtistName() { + return artistName; + } + + public String getRecordedAt() { + return recordedAt; + } + + public String getCity() { + return city; + } + + public int getPosition() { + return position; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryComposed.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryComposed.java new file mode 100644 index 0000000000..2543c70686 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryComposed.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Filip Hrisafov + */ +public class ChartEntryComposed { + + private String chartName; + private String songTitle; + private String artistName; + private ChartEntryLabel label; + private int position; + + public String getChartName() { + return chartName; + } + + public void setChartName(String chartName) { + this.chartName = chartName; + } + + public String getSongTitle() { + return songTitle; + } + + public void setSongTitle(String songTitle) { + this.songTitle = songTitle; + } + + public String getArtistName() { + return artistName; + } + + public void setArtistName(String artistName) { + this.artistName = artistName; + } + + public ChartEntryLabel getLabel() { + return label; + } + + public void setLabel(ChartEntryLabel label) { + this.label = label; + } + + public int getPosition() { + return position; + } + + public void setPosition(int position) { + this.position = position; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryLabel.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryLabel.java new file mode 100644 index 0000000000..b639b97b35 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryLabel.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Filip Hrisafov + */ +public class ChartEntryLabel { + + private final String name; + private final String city; + private final String recordedAt; + + public ChartEntryLabel(String name, String city, String recordedAt) { + this.name = name; + this.city = city; + this.recordedAt = recordedAt; + } + + public String getName() { + return name; + } + + public String getCity() { + return city; + } + + public String getRecordedAt() { + return recordedAt; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryWithBase.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryWithBase.java new file mode 100644 index 0000000000..4855080fb3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryWithBase.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Filip Hrisafov + */ +public class ChartEntryWithBase extends BaseChartEntry { + + private final String recordedAt; + private final String city; + private final int position; + + public ChartEntryWithBase(String chartName, String songTitle, String artistName, String recordedAt, + String city, int position) { + super( chartName, songTitle, artistName ); + this.recordedAt = recordedAt; + this.city = city; + this.position = position; + } + + public String getRecordedAt() { + return recordedAt; + } + + public String getCity() { + return city; + } + + public int getPosition() { + return position; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryWithMapping.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryWithMapping.java new file mode 100644 index 0000000000..f7ba366e17 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartEntryWithMapping.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +/** + * @author Filip Hrisafov + */ +public class ChartEntryWithMapping { + + private final String chartName; + private final String songTitle; + private final int artistId; + private final String recordedAt; + private final String city; + private final int position; + + public ChartEntryWithMapping(String chartName, String songTitle, int artistId, String recordedAt, + String city, int position) { + this.chartName = chartName; + this.songTitle = songTitle; + this.artistId = artistId; + this.recordedAt = recordedAt; + this.city = city; + this.position = position; + } + + public String getChartName() { + return chartName; + } + + public String getSongTitle() { + return songTitle; + } + + public int getArtistId() { + return artistId; + } + + public String getRecordedAt() { + return recordedAt; + } + + public String getCity() { + return city; + } + + public int getPosition() { + return position; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartPositions.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartPositions.java new file mode 100644 index 0000000000..a14e04ac76 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/_target/ChartPositions.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource._target; + +import java.util.Collections; +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class ChartPositions { + + private final List positions; + + public ChartPositions(List positions) { + this.positions = positions; + } + + public List getPositions() { + return Collections.unmodifiableList( positions ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Artist.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Artist.java new file mode 100644 index 0000000000..def4ac697f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Artist.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource.source; + +/** + * @author Filip Hrisafov + */ +public class Artist { + + private final String name; + private final Label label; + + public Artist(String name, Label label) { + this.name = name; + this.label = label; + } + + public String getName() { + return name; + } + + public Label getLabel() { + return label; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Chart.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Chart.java new file mode 100644 index 0000000000..064129fc06 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Chart.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource.source; + +/** + * @author Filip Hrisafov + */ +public class Chart { + + private final String type; + private final String name; + private final Song song; + + public Chart(String type, String name, Song song) { + this.type = type; + this.name = name; + this.song = song; + } + + public String getType() { + return type; + } + + public String getName() { + return name; + } + + public Song getSong() { + return song; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Label.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Label.java new file mode 100644 index 0000000000..6c2a15bbfb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Label.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource.source; + +/** + * @author Filip Hrisafov + */ +public class Label { + + private final String name; + private final Studio studio; + + public Label(String name, Studio studio) { + this.name = name; + this.studio = studio; + } + + public String getName() { + return name; + } + + public Studio getStudio() { + return studio; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Song.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Song.java new file mode 100644 index 0000000000..ac6ce20104 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Song.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource.source; + +import java.util.List; + +/** + * @author Filip Hrisafov + */ +public class Song { + + private final Artist artist; + private final String title; + private final List positions; + + public Song(Artist artist, String title, List positions) { + this.artist = artist; + this.title = title; + this.positions = positions; + } + + public Artist getArtist() { + return artist; + } + + public String getTitle() { + return title; + } + + public List getPositions() { + return positions; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Studio.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Studio.java new file mode 100644 index 0000000000..db7bfd7389 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedsource/source/Studio.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedsource.source; + +/** + * @author Filip Hrisafov + */ +public class Studio { + + private final String name; + private final String city; + + public Studio(String name, String city) { + this.name = name; + this.city = city; + } + + public String getName() { + return name; + } + + public String getCity() { + return city; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedtarget/ChartEntryToArtist.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedtarget/ChartEntryToArtist.java new file mode 100644 index 0000000000..9c1946fa26 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedtarget/ChartEntryToArtist.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedtarget; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Mappings; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Chart; +import org.mapstruct.factory.Mappers; + +/** + * @author Sjaak Derksen + */ +@Mapper +public abstract class ChartEntryToArtist { + + public static final ChartEntryToArtist MAPPER = Mappers.getMapper( ChartEntryToArtist.class ); + + @Mappings({ + @Mapping(target = "type", ignore = true), + @Mapping(target = "name", source = "chartName"), + @Mapping(target = "song.title", source = "songTitle"), + @Mapping(target = "song.artist.name", source = "artistName"), + @Mapping(target = "song.artist.label.studio.name", source = "recordedAt"), + @Mapping(target = "song.artist.label.studio.city", source = "city"), + @Mapping(target = "song.positions", source = "position") + }) + public abstract Chart map(ChartEntry chartEntry); + + @InheritInverseConfiguration + public abstract ChartEntry map(Chart chart); + + protected List mapPosition(Integer in) { + if ( in != null ) { + return new ArrayList<>( Arrays.asList( in ) ); + } + else { + return new ArrayList<>(); + } + } + + protected Integer mapPosition(List in) { + if ( in != null && !in.isEmpty() ) { + return in.get( 0 ); + } + else { + return null; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedtarget/NestedProductPropertiesConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedtarget/NestedProductPropertiesConstructorTest.java new file mode 100644 index 0000000000..c5cbe8279c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/nestedtarget/NestedProductPropertiesConstructorTest.java @@ -0,0 +1,95 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.nestedtarget; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.constructor.nestedsource._target.ChartEntry; +import org.mapstruct.ap.test.constructor.nestedsource.source.Artist; +import org.mapstruct.ap.test.constructor.nestedsource.source.Chart; +import org.mapstruct.ap.test.constructor.nestedsource.source.Label; +import org.mapstruct.ap.test.constructor.nestedsource.source.Song; +import org.mapstruct.ap.test.constructor.nestedsource.source.Studio; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@WithClasses({ + Song.class, + Artist.class, + Chart.class, + Label.class, + Studio.class, + ChartEntry.class, + ChartEntryToArtist.class, +}) +@IssueKey("73") +public class NestedProductPropertiesConstructorTest { + + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + ChartEntryToArtist.class + ); + + @ProcessorTest + public void shouldMapNestedTarget() { + + ChartEntry chartEntry = new ChartEntry( + "US Billboard Hot Rock Songs", + "Purple Rain", + "Prince", + "Live, First Avenue, Minneapolis", + "Minneapolis", + 1 + ); + + Chart result = ChartEntryToArtist.MAPPER.map( chartEntry ); + + assertThat( result.getName() ).isEqualTo( "US Billboard Hot Rock Songs" ); + assertThat( result.getSong() ).isNotNull(); + assertThat( result.getSong().getArtist() ).isNotNull(); + assertThat( result.getSong().getTitle() ).isEqualTo( "Purple Rain" ); + assertThat( result.getSong().getArtist().getName() ).isEqualTo( "Prince" ); + assertThat( result.getSong().getArtist().getLabel() ).isNotNull(); + assertThat( result.getSong().getArtist().getLabel().getStudio() ).isNotNull(); + assertThat( result.getSong().getArtist().getLabel().getStudio().getName() ) + .isEqualTo( "Live, First Avenue, Minneapolis" ); + assertThat( result.getSong().getArtist().getLabel().getStudio().getCity() ) + .isEqualTo( "Minneapolis" ); + assertThat( result.getSong().getPositions() ).hasSize( 1 ); + assertThat( result.getSong().getPositions().get( 0 ) ).isEqualTo( 1 ); + + } + + @ProcessorTest + public void shouldReverseNestedTarget() { + + ChartEntry chartEntry = new ChartEntry( + "US Billboard Hot Rock Songs", + "Purple Rain", + "Prince", + "Live, First Avenue, Minneapolis", + "Minneapolis", + 1 + ); + + Chart chart = ChartEntryToArtist.MAPPER.map( chartEntry ); + ChartEntry result = ChartEntryToArtist.MAPPER.map( chart ); + + assertThat( result ).isNotNull(); + assertThat( result.getArtistName() ).isEqualTo( "Prince" ); + assertThat( result.getChartName() ).isEqualTo( "US Billboard Hot Rock Songs" ); + assertThat( result.getCity() ).isEqualTo( "Minneapolis" ); + assertThat( result.getPosition() ).isEqualTo( 1 ); + assertThat( result.getRecordedAt() ).isEqualTo( "Live, First Avenue, Minneapolis" ); + assertThat( result.getSongTitle() ).isEqualTo( "Purple Rain" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/simple/SimpleConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/simple/SimpleConstructorMapper.java new file mode 100644 index 0000000000..2e162d2f23 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/simple/SimpleConstructorMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.simple; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.constructor.Person; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleConstructorMapper { + + SimpleConstructorMapper INSTANCE = Mappers.getMapper( SimpleConstructorMapper.class ); + + Person map(PersonDto dto); + + @Mapping(target = "age", constant = "25") + @Mapping(target = "job", constant = "Software Developer") + Person mapWithConstants(PersonDto dto); + + @Mapping(target = "age", expression = "java(25 - 5)") + @Mapping(target = "job", expression = "java(\"Software Developer\".toLowerCase())") + Person mapWithExpression(PersonDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/simple/SimpleConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/simple/SimpleConstructorTest.java new file mode 100644 index 0000000000..49bb7e6d8a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/simple/SimpleConstructorTest.java @@ -0,0 +1,86 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.simple; + +import java.util.Arrays; + +import org.mapstruct.ap.test.constructor.Person; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Person.class, + PersonDto.class, + SimpleConstructorMapper.class +}) +public class SimpleConstructorTest { + + @ProcessorTest + public void mapDefault() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + Person target = SimpleConstructorMapper.INSTANCE.map( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 30 ); + assertThat( target.getJob() ).isEqualTo( "Software Engineer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } + + @ProcessorTest + public void mapWithConstants() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + Person target = SimpleConstructorMapper.INSTANCE.mapWithConstants( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 25 ); + assertThat( target.getJob() ).isEqualTo( "Software Developer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } + + @ProcessorTest + public void mapWithExpressions() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + source.setJob( "Software Engineer" ); + source.setCity( "Zurich" ); + source.setAddress( "Plaza 1" ); + source.setChildren( Arrays.asList( "Alice", "Tom" ) ); + + Person target = SimpleConstructorMapper.INSTANCE.mapWithExpression( source ); + + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 20 ); + assertThat( target.getJob() ).isEqualTo( "software developer" ); + assertThat( target.getCity() ).isEqualTo( "Zurich" ); + assertThat( target.getAddress() ).isEqualTo( "Plaza 1" ); + assertThat( target.getChildren() ).containsExactly( "Alice", "Tom" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/Order.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/Order.java new file mode 100644 index 0000000000..18fe9b1015 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/Order.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.unmapped; + +import java.util.Date; + +/** + * @author Filip Hrisafov + */ +public class Order { + + private final String name; + private final Date time; + + public Order(String name, Date time) { + this.name = name; + this.time = time; + } + + public String getName() { + return name; + } + + public Date getTime() { + return time; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/OrderDto.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/OrderDto.java new file mode 100644 index 0000000000..259cf8973d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/OrderDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.unmapped; + +/** + * @author Filip Hrisafov + */ +public class OrderDto { + + private final String name; + + public OrderDto(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/UnmappedConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/UnmappedConstructorMapper.java new file mode 100644 index 0000000000..8fcede06f4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/UnmappedConstructorMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.unmapped; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface UnmappedConstructorMapper { + + UnmappedConstructorMapper INSTANCE = Mappers.getMapper( UnmappedConstructorMapper.class ); + + Order map(OrderDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/UnmappedConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/UnmappedConstructorTest.java new file mode 100644 index 0000000000..0e35361f48 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/unmapped/UnmappedConstructorTest.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.unmapped; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + Order.class, + OrderDto.class, + UnmappedConstructorMapper.class +}) +public class UnmappedConstructorTest { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = UnmappedConstructorMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 19, + message = "Unmapped target property: \"time\".") + }) + public void shouldGenerateCompilableCodeForUnmappedConstructorProperties() { + OrderDto source = new OrderDto( "truck" ); + + Order target = UnmappedConstructorMapper.INSTANCE.map( source ); + + assertThat( target.getName() ).isEqualTo( "truck" ); + assertThat( target.getTime() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/ConstructorVisibilityTest.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/ConstructorVisibilityTest.java new file mode 100644 index 0000000000..5eebaf5d05 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/ConstructorVisibilityTest.java @@ -0,0 +1,88 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.visibility; + +import org.mapstruct.ap.test.constructor.Default; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2150") +@WithClasses({ + PersonDto.class, + Default.class, +}) +public class ConstructorVisibilityTest { + + @ProcessorTest + @WithClasses({ + SimpleWithPublicConstructorMapper.class + }) + public void shouldUseSinglePublicConstructorAlways() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + + SimpleWithPublicConstructorMapper.Person target = + SimpleWithPublicConstructorMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 30 ); + } + + @ProcessorTest + @WithClasses({ + SimpleWithPublicParameterlessConstructorMapper.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = SimpleWithPublicParameterlessConstructorMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 21, + message = "No target property found for target " + + "\"SimpleWithPublicParameterlessConstructorMapper.Person\"."), + }) + + public void shouldUsePublicParameterConstructorIfPresent() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + + SimpleWithPublicParameterlessConstructorMapper.Person target = + SimpleWithPublicParameterlessConstructorMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "From Constructor" ); + assertThat( target.getAge() ).isEqualTo( -1 ); + } + + @ProcessorTest + @WithClasses({ + SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.class + }) + public void shouldUseDefaultAnnotatedConstructorAlways() { + PersonDto source = new PersonDto(); + source.setName( "Bob" ); + source.setAge( 30 ); + + SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.Person target = + SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "Bob" ); + assertThat( target.getAge() ).isEqualTo( 30 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicConstructorMapper.java new file mode 100644 index 0000000000..ce0a98aa34 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicConstructorMapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.visibility; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleWithPublicConstructorMapper { + + SimpleWithPublicConstructorMapper INSTANCE = Mappers.getMapper( SimpleWithPublicConstructorMapper.class ); + + Person map(PersonDto dto); + + class Person { + + private final String name; + private final int age; + + protected Person() { + this( "From Constructor", -1 ); + } + + protected Person(String name) { + this( name, -1 ); + } + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.java new file mode 100644 index 0000000000..923821681a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.visibility; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.constructor.Default; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper { + + SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper INSTANCE = Mappers.getMapper( + SimpleWithPublicParameterlessConstructorAndDefaultAnnotatedMapper.class ); + + Person map(PersonDto dto); + + class Person { + + private final String name; + private final int age; + + protected Person() { + this( "From Constructor", -1 ); + } + + protected Person(String name) { + this( name, -1 ); + } + + @Default + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicParameterlessConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicParameterlessConstructorMapper.java new file mode 100644 index 0000000000..c0ba14bc42 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/constructor/visibility/SimpleWithPublicParameterlessConstructorMapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.constructor.visibility; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.constructor.PersonDto; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleWithPublicParameterlessConstructorMapper { + + SimpleWithPublicParameterlessConstructorMapper INSTANCE = Mappers.getMapper( + SimpleWithPublicParameterlessConstructorMapper.class ); + + Person map(PersonDto dto); + + class Person { + + private final String name; + private final int age; + + public Person() { + this( "From Constructor", -1 ); + } + + protected Person(String name) { + this( name, -1 ); + } + + public Person(String name, int age) { + this.name = name; + this.age = age; + } + + public String getName() { + return name; + } + + public int getAge() { + return age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithContext.java b/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithContext.java index a0afc9af5f..21a93fab82 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithSelfContainingContext.java b/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithSelfContainingContext.java index af3ffc396f..1e59c275c6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithSelfContainingContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/AutomappingNodeMapperWithSelfContainingContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterErroneousTest.java b/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterErroneousTest.java index 89a226eb22..46bb08cb70 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterErroneousTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterErroneousTest.java @@ -1,40 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.Context; import org.mapstruct.ap.test.context.erroneous.ErroneousNodeMapperWithNonUniqueContextTypes; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Tests the erroneous usage of the {@link Context} annotation in the following situations: *
        - *
      • using the the same context parameter type twice in the same method + *
      • using the same context parameter type twice in the same method *
      * * @author Andreas Gudian @@ -44,17 +29,16 @@ Node.class, NodeDto.class, CycleContext.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ContextParameterErroneousTest { - @Test + @ProcessorTest @WithClasses(ErroneousNodeMapperWithNonUniqueContextTypes.class) @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = @Diagnostic( kind = Kind.ERROR, - line = 33, + line = 20, type = ErroneousNodeMapperWithNonUniqueContextTypes.class, - messageRegExp = "The types of @Context parameters must be unique")) + message = "The types of @Context parameters must be unique.")) public void reportsNonUniqueContextParamType() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterTest.java b/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterTest.java index b84fa21ec3..017183743b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/ContextParameterTest.java @@ -1,35 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.BeforeMapping; import org.mapstruct.Context; import org.mapstruct.ObjectFactory; import org.mapstruct.ap.test.context.Node.Attribute; import org.mapstruct.ap.test.context.NodeDto.AttributeDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests the usage of the {@link Context} annotation in the following situations: @@ -57,12 +42,11 @@ CycleContextLifecycleMethods.class, FactoryContextMethods.class, SelfContainingCycleContext.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ContextParameterTest { private static final int MAGIC_NUMBER_OFFSET = 10; - @Test + @ProcessorTest public void mappingWithContextCorrectlyResolvesCycles() { Node root = buildNodes(); NodeDto rootDto = @@ -74,7 +58,7 @@ public void mappingWithContextCorrectlyResolvesCycles() { assertResult( updated ); } - @Test + @ProcessorTest public void automappingWithContextCorrectlyResolvesCycles() { Node root = buildNodes(); NodeDto rootDto = AutomappingNodeMapperWithContext.INSTANCE @@ -87,7 +71,7 @@ public void automappingWithContextCorrectlyResolvesCycles() { assertResult( updated ); } - @Test + @ProcessorTest public void automappingWithSelfContainingContextCorrectlyResolvesCycles() { Node root = buildNodes(); NodeDto rootDto = AutomappingNodeMapperWithSelfContainingContext.INSTANCE diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/CycleContext.java b/processor/src/test/java/org/mapstruct/ap/test/context/CycleContext.java index 713817eb8f..da6c87ecdf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/CycleContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/CycleContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; @@ -29,7 +16,7 @@ * @author Andreas Gudian */ public class CycleContext { - private Map knownInstances = new IdentityHashMap(); + private Map knownInstances = new IdentityHashMap<>(); @SuppressWarnings("unchecked") public T getMappedInstance(Object source, Class targetType) { diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/CycleContextLifecycleMethods.java b/processor/src/test/java/org/mapstruct/ap/test/context/CycleContextLifecycleMethods.java index ffb2a970f4..edca0142d5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/CycleContextLifecycleMethods.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/CycleContextLifecycleMethods.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContext.java b/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContext.java index df6b07ddce..28194513bd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContextMethods.java b/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContextMethods.java index 6eb9ddbd4a..87908f1238 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContextMethods.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/FactoryContextMethods.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/Node.java b/processor/src/test/java/org/mapstruct/ap/test/context/Node.java index 07b9237042..b663b7b15f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/Node.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/Node.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; @@ -34,8 +21,8 @@ public class Node { public Node(String name) { this.name = name; - this.children = new ArrayList(); - this.attributes = new ArrayList(); + this.children = new ArrayList<>(); + this.attributes = new ArrayList<>(); } public Node getParent() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/NodeDto.java b/processor/src/test/java/org/mapstruct/ap/test/context/NodeDto.java index 2bfb2978cd..0d117aa487 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/NodeDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/NodeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/NodeMapperWithContext.java b/processor/src/test/java/org/mapstruct/ap/test/context/NodeMapperWithContext.java index 374363f9b4..8ebdb5c64a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/NodeMapperWithContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/NodeMapperWithContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/SelfContainingCycleContext.java b/processor/src/test/java/org/mapstruct/ap/test/context/SelfContainingCycleContext.java index 7f062d5c7d..8b4a21640f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/SelfContainingCycleContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/SelfContainingCycleContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context; @@ -32,7 +19,7 @@ * @author Andreas Gudian */ public class SelfContainingCycleContext { - private Map knownInstances = new IdentityHashMap(); + private Map knownInstances = new IdentityHashMap<>(); @BeforeMapping @SuppressWarnings("unchecked") diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/erroneous/ErroneousNodeMapperWithNonUniqueContextTypes.java b/processor/src/test/java/org/mapstruct/ap/test/context/erroneous/ErroneousNodeMapperWithNonUniqueContextTypes.java index 98ddb2e08f..210f7fc968 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/erroneous/ErroneousNodeMapperWithNonUniqueContextTypes.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/erroneous/ErroneousNodeMapperWithNonUniqueContextTypes.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextObjectFactory.java b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextObjectFactory.java index 2ef29aa363..af0e8b5145 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextObjectFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextObjectFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context.objectfactory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryMapper.java index febf62e0e1..b82d07f042 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context.objectfactory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryTest.java index 15da66770d..068a5a0d95 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ContextWithObjectFactoryTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context.objectfactory; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @@ -36,10 +21,9 @@ ValveDto.class, ContextObjectFactory.class, ContextWithObjectFactoryMapper.class}) -@RunWith(AnnotationProcessorTestRunner.class) public class ContextWithObjectFactoryTest { - @Test + @ProcessorTest public void testFactoryCalled( ) { ValveDto dto = new ValveDto(); dto.setOneWay( true ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/Valve.java b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/Valve.java index 4a04bdd816..887c4b3ec9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/Valve.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/Valve.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context.objectfactory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ValveDto.java b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ValveDto.java index 1a4a96e342..10c148f484 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ValveDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/context/objectfactory/ValveDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.context.objectfactory; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/ConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/ConversionTest.java index 521be1f50e..d59f069458 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/ConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/ConversionTest.java @@ -1,35 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ConversionTest { - @Test + @ProcessorTest public void shouldApplyConversions() { Source source = new Source(); source.setFoo( 42 ); @@ -44,7 +28,7 @@ public void shouldApplyConversions() { assertThat( target.getZip() ).isEqualTo( "73" ); } - @Test + @ProcessorTest public void shouldHandleNulls() { Source source = new Source(); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -55,7 +39,7 @@ public void shouldHandleNulls() { assertThat( target.getZip() ).isEqualTo( "0" ); } - @Test + @ProcessorTest public void shouldApplyConversionsToMappedProperties() { Source source = new Source(); source.setQax( 42 ); @@ -68,7 +52,7 @@ public void shouldApplyConversionsToMappedProperties() { assertThat( target.getQax() ).isEqualTo( 23 ); } - @Test + @ProcessorTest public void shouldApplyConversionsForReverseMapping() { Target target = new Target(); target.setFoo( 42L ); @@ -83,7 +67,7 @@ public void shouldApplyConversionsForReverseMapping() { assertThat( source.getZip() ).isEqualTo( 73 ); } - @Test + @ProcessorTest public void shouldApplyConversionsToMappedPropertiesForReverseMapping() { Target target = new Target(); target.setQax( 42 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/Source.java index 7c6858900c..78cb134897 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/SourceTargetMapper.java index 683f583427..0bd3888809 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion; @@ -30,8 +17,8 @@ public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mappings({ - @Mapping(source = "qax", target = "baz"), - @Mapping(source = "baz", target = "qax") + @Mapping(target = "baz", source = "qax"), + @Mapping(target = "qax", source = "baz") }) Target sourceToTarget(Source source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/Target.java index 23de76c88a..8056ab6aa3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerConversionTest.java new file mode 100644 index 0000000000..67d99dfbc6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerConversionTest.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests conversions between {@link Enum} and Integer. + * + * @author Jose Carlos Campanero Ortiz + */ +@IssueKey("2963") +@WithClasses({ + EnumToIntegerSource.class, + EnumToIntegerTarget.class, + EnumToIntegerMapper.class, + EnumToIntegerEnum.class +}) +public class EnumToIntegerConversionTest { + + @ProcessorTest + public void shouldApplyEnumToIntegerConversion() { + EnumToIntegerSource source = new EnumToIntegerSource(); + + for ( EnumToIntegerEnum value : EnumToIntegerEnum.values() ) { + source.setEnumValue( value ); + + EnumToIntegerTarget target = EnumToIntegerMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getEnumValue() ).isEqualTo( source.getEnumValue().ordinal() ); + } + } + + @ProcessorTest + public void shouldApplyReverseEnumToIntegerConversion() { + EnumToIntegerTarget target = new EnumToIntegerTarget(); + + int numberOfValues = EnumToIntegerEnum.values().length; + for ( int value = 0; value < numberOfValues; value++ ) { + target.setEnumValue( value ); + + EnumToIntegerSource source = EnumToIntegerMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getEnumValue() ).isEqualTo( EnumToIntegerEnum.values()[ target.getEnumValue() ] ); + } + } + + @ProcessorTest + public void shouldHandleOutOfBoundsEnumOrdinal() { + EnumToIntegerTarget target = new EnumToIntegerTarget(); + target.setInvalidEnumValue( EnumToIntegerEnum.values().length + 1 ); + + assertThatThrownBy( () -> EnumToIntegerMapper.INSTANCE.targetToSource( target ) ) + .isInstanceOf( ArrayIndexOutOfBoundsException.class ); + } + + @ProcessorTest + public void shouldHandleNullIntegerValue() { + EnumToIntegerTarget target = new EnumToIntegerTarget(); + + EnumToIntegerSource source = EnumToIntegerMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getEnumValue() ).isNull(); + assertThat( source.getInvalidEnumValue() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerEnum.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerEnum.java new file mode 100644 index 0000000000..4aad7bef57 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerEnum.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +public enum EnumToIntegerEnum { + ARBITRARY_VALUE_ZERO, + ARBITRARY_VALUE_ONE, + ARBITRARY_VALUE_TWO, + ARBITRARY_VALUE_THREE +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerMapper.java new file mode 100644 index 0000000000..946ee7c463 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface EnumToIntegerMapper { + EnumToIntegerMapper INSTANCE = Mappers.getMapper( EnumToIntegerMapper.class ); + + EnumToIntegerTarget sourceToTarget(EnumToIntegerSource source); + + EnumToIntegerSource targetToSource(EnumToIntegerTarget target); +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerSource.java new file mode 100644 index 0000000000..4e60311d9b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerSource.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +public class EnumToIntegerSource { + private EnumToIntegerEnum enumValue; + + private EnumToIntegerEnum invalidEnumValue; + + public EnumToIntegerEnum getEnumValue() { + return enumValue; + } + + public void setEnumValue(final EnumToIntegerEnum enumValue) { + this.enumValue = enumValue; + } + + public EnumToIntegerEnum getInvalidEnumValue() { + return invalidEnumValue; + } + + public void setInvalidEnumValue(EnumToIntegerEnum invalidEnumValue) { + this.invalidEnumValue = invalidEnumValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerTarget.java new file mode 100644 index 0000000000..a8819c27ed --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/EnumToIntegerTarget.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +public class EnumToIntegerTarget { + private Integer enumValue; + + private Integer invalidEnumValue; + + public Integer getEnumValue() { + return enumValue; + } + + public void setEnumValue(final Integer enumValue) { + this.enumValue = enumValue; + } + + public Integer getInvalidEnumValue() { + return invalidEnumValue; + } + + public void setInvalidEnumValue(Integer invalidEnumValue) { + this.invalidEnumValue = invalidEnumValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerConversionTest.java new file mode 100644 index 0000000000..e1e557a897 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerConversionTest.java @@ -0,0 +1,73 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +import java.util.Optional; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +@WithClasses({ + OptionalEnumToIntegerSource.class, + EnumToIntegerTarget.class, + OptionalEnumToIntegerMapper.class, + EnumToIntegerEnum.class +}) +public class OptionalEnumToIntegerConversionTest { + + @ProcessorTest + public void shouldApplyEnumToIntegerConversion() { + OptionalEnumToIntegerSource source = new OptionalEnumToIntegerSource(); + + for ( EnumToIntegerEnum value : EnumToIntegerEnum.values() ) { + source.setEnumValue( Optional.of( value ) ); + + EnumToIntegerTarget target = OptionalEnumToIntegerMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getEnumValue() ).isEqualTo( value.ordinal() ); + } + } + + @ProcessorTest + public void shouldApplyReverseEnumToIntegerConversion() { + EnumToIntegerTarget target = new EnumToIntegerTarget(); + + EnumToIntegerEnum[] enumValues = EnumToIntegerEnum.values(); + int numberOfValues = enumValues.length; + for ( int value = 0; value < numberOfValues; value++ ) { + target.setEnumValue( value ); + + OptionalEnumToIntegerSource source = OptionalEnumToIntegerMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getEnumValue() ).contains( enumValues[target.getEnumValue()] ); + } + } + + @ProcessorTest + public void shouldHandleOutOfBoundsEnumOrdinal() { + EnumToIntegerTarget target = new EnumToIntegerTarget(); + target.setInvalidEnumValue( EnumToIntegerEnum.values().length + 1 ); + + assertThatThrownBy( () -> OptionalEnumToIntegerMapper.INSTANCE.targetToSource( target ) ) + .isInstanceOf( ArrayIndexOutOfBoundsException.class ); + } + + @ProcessorTest + public void shouldHandleNullIntegerValue() { + EnumToIntegerTarget target = new EnumToIntegerTarget(); + + OptionalEnumToIntegerSource source = OptionalEnumToIntegerMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getEnumValue() ).isEmpty(); + assertThat( source.getInvalidEnumValue() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerMapper.java new file mode 100644 index 0000000000..d07d9b879c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface OptionalEnumToIntegerMapper { + OptionalEnumToIntegerMapper INSTANCE = Mappers.getMapper( OptionalEnumToIntegerMapper.class ); + + EnumToIntegerTarget sourceToTarget(OptionalEnumToIntegerSource source); + + OptionalEnumToIntegerSource targetToSource(EnumToIntegerTarget target); +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerSource.java new file mode 100644 index 0000000000..700c3198bc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/_enum/OptionalEnumToIntegerSource.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion._enum; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class OptionalEnumToIntegerSource { + private Optional enumValue = Optional.empty(); + + private Optional invalidEnumValue = Optional.empty(); + + public Optional getEnumValue() { + return enumValue; + } + + public void setEnumValue(Optional enumValue) { + this.enumValue = enumValue; + } + + public Optional getInvalidEnumValue() { + return invalidEnumValue; + } + + public void setInvalidEnumValue(Optional invalidEnumValue) { + this.invalidEnumValue = invalidEnumValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalMapper.java index ff92d16334..30bd6ba9ad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalOptionalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalOptionalMapper.java new file mode 100644 index 0000000000..986de6a0ed --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalOptionalMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.bignumbers; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface BigDecimalOptionalMapper { + + BigDecimalOptionalMapper INSTANCE = Mappers.getMapper( BigDecimalOptionalMapper.class ); + + BigDecimalTarget sourceToTarget(BigDecimalOptionalSource source); + + BigDecimalOptionalSource targetToSource(BigDecimalTarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalOptionalSource.java new file mode 100644 index 0000000000..bf4e53e5d9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalOptionalSource.java @@ -0,0 +1,139 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.bignumbers; + +import java.math.BigDecimal; +import java.util.Optional; + +public class BigDecimalOptionalSource { + + private Optional b; + private Optional bb; + private Optional s; + private Optional ss; + private Optional i; + private Optional ii; + private Optional l; + private Optional ll; + private Optional f; + private Optional ff; + private Optional d; + private Optional dd; + private Optional string; + private Optional bigInteger; + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } + + public Optional getString() { + return string; + } + + public void setString(Optional string) { + this.string = string; + } + + public Optional getBigInteger() { + return bigInteger; + } + + public void setBigInteger(Optional bigInteger) { + this.bigInteger = bigInteger; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalSource.java index 8413063ee4..d52cb69f41 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalTarget.java index 5a187c4266..18843a25dd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigDecimalTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerMapper.java index 3692ca2221..1663df8f51 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerOptionalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerOptionalMapper.java new file mode 100644 index 0000000000..d39b48c7e5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerOptionalMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.bignumbers; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface BigIntegerOptionalMapper { + + BigIntegerOptionalMapper INSTANCE = Mappers.getMapper( BigIntegerOptionalMapper.class ); + + BigIntegerTarget sourceToTarget(BigIntegerOptionalSource source); + + BigIntegerOptionalSource targetToSource(BigIntegerTarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerOptionalSource.java new file mode 100644 index 0000000000..f4bb0f03c8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerOptionalSource.java @@ -0,0 +1,131 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.bignumbers; + +import java.math.BigInteger; +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class BigIntegerOptionalSource { + + private Optional b; + private Optional bb; + private Optional s; + private Optional ss; + private Optional i; + private Optional ii; + private Optional l; + private Optional ll; + private Optional f; + private Optional ff; + private Optional d; + private Optional dd; + private Optional string; + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } + + public Optional getString() { + return string; + } + + public void setString(Optional string) { + this.string = string; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerSource.java index cbbe012b4b..34821583cd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerTarget.java index ed33131c64..4204715d3b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigIntegerTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigNumbersConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigNumbersConversionTest.java index eef41167b9..2ddddec02e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigNumbersConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/bignumbers/BigNumbersConversionTest.java @@ -1,52 +1,33 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.bignumbers; -import static org.assertj.core.api.Assertions.assertThat; - import java.math.BigDecimal; import java.math.BigInteger; -import org.junit.Rule; +import java.util.Optional; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * Tests conversions between {@link BigInteger} and numbers as well as String. * * @author Gunnar Morling */ -@RunWith(AnnotationProcessorTestRunner.class) public class BigNumbersConversionTest { - private final GeneratedSource generatedSource = new GeneratedSource(); - - @Rule - public GeneratedSource getGeneratedSource() { - return generatedSource; - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @IssueKey("21") @WithClasses({ BigIntegerSource.class, BigIntegerTarget.class, BigIntegerMapper.class }) public void shouldApplyBigIntegerConversions() { @@ -83,7 +64,7 @@ public void shouldApplyBigIntegerConversions() { assertThat( target.getString() ).isEqualTo( "13" ); } - @Test + @ProcessorTest @IssueKey("21") @WithClasses({ BigIntegerSource.class, BigIntegerTarget.class, BigIntegerMapper.class }) public void shouldApplyReverseBigIntegerConversions() { @@ -120,7 +101,80 @@ public void shouldApplyReverseBigIntegerConversions() { assertThat( source.getString() ).isEqualTo( new BigInteger( "13" ) ); } - @Test + @ProcessorTest + @WithClasses({ BigIntegerOptionalSource.class, BigIntegerTarget.class, BigIntegerOptionalMapper.class }) + public void shouldApplyOptionalBigIntegerConversions() { + BigIntegerOptionalSource source = new BigIntegerOptionalSource(); + source.setB( Optional.of( new BigInteger( "1" ) ) ); + source.setBb( Optional.of( new BigInteger( "2" ) ) ); + source.setS( Optional.of( new BigInteger( "3" ) ) ); + source.setSs( Optional.of( new BigInteger( "4" ) ) ); + source.setI( Optional.of( new BigInteger( "5" ) ) ); + source.setIi( Optional.of( new BigInteger( "6" ) ) ); + source.setL( Optional.of( new BigInteger( "7" ) ) ); + source.setLl( Optional.of( new BigInteger( "8" ) ) ); + source.setF( Optional.of( new BigInteger( "9" ) ) ); + source.setFf( Optional.of( new BigInteger( "10" ) ) ); + source.setD( Optional.of( new BigInteger( "11" ) ) ); + source.setDd( Optional.of( new BigInteger( "12" ) ) ); + source.setString( Optional.of( new BigInteger( "13" ) ) ); + + BigIntegerTarget target = BigIntegerOptionalMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( (byte) 2 ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( (short) 4 ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( 6 ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( 8 ); + assertThat( target.getF() ).isEqualTo( 9.0f ); + assertThat( target.getFf() ).isEqualTo( 10.0f ); + assertThat( target.getD() ).isEqualTo( 11.0d ); + assertThat( target.getDd() ).isEqualTo( 12.0d ); + assertThat( target.getString() ).isEqualTo( "13" ); + } + + @ProcessorTest + @IssueKey("21") + @WithClasses({ BigIntegerOptionalSource.class, BigIntegerTarget.class, BigIntegerOptionalMapper.class }) + public void shouldApplyReverseOptionalBigIntegerConversions() { + BigIntegerTarget target = new BigIntegerTarget(); + target.setB( (byte) 1 ); + target.setBb( (byte) 2 ); + target.setS( (short) 3 ); + target.setSs( (short) 4 ); + target.setI( 5 ); + target.setIi( 6 ); + target.setL( 7 ); + target.setLl( 8L ); + target.setF( 9.0f ); + target.setFf( 10.0f ); + target.setD( 11.0d ); + target.setDd( 12.0d ); + target.setString( "13" ); + + BigIntegerOptionalSource source = BigIntegerOptionalMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getB() ).contains( new BigInteger( "1" ) ); + assertThat( source.getBb() ).contains( new BigInteger( "2" ) ); + assertThat( source.getS() ).contains( new BigInteger( "3" ) ); + assertThat( source.getSs() ).contains( new BigInteger( "4" ) ); + assertThat( source.getI() ).contains( new BigInteger( "5" ) ); + assertThat( source.getIi() ).contains( new BigInteger( "6" ) ); + assertThat( source.getL() ).contains( new BigInteger( "7" ) ); + assertThat( source.getLl() ).contains( new BigInteger( "8" ) ); + assertThat( source.getF() ).contains( new BigInteger( "9" ) ); + assertThat( source.getFf() ).contains( new BigInteger( "10" ) ); + assertThat( source.getD() ).contains( new BigInteger( "11" ) ); + assertThat( source.getDd() ).contains( new BigInteger( "12" ) ); + assertThat( source.getString() ).contains( new BigInteger( "13" ) ); + } + + @ProcessorTest @IssueKey("21") @WithClasses({ BigDecimalSource.class, BigDecimalTarget.class, BigDecimalMapper.class }) public void shouldApplyBigDecimalConversions() { @@ -159,7 +213,7 @@ public void shouldApplyBigDecimalConversions() { assertThat( target.getBigInteger() ).isEqualTo( new BigInteger( "14" ) ); } - @Test + @ProcessorTest @IssueKey("21") @WithClasses({ BigDecimalSource.class, BigDecimalTarget.class, BigDecimalMapper.class }) public void shouldApplyReverseBigDecimalConversions() { @@ -198,10 +252,86 @@ public void shouldApplyReverseBigDecimalConversions() { assertThat( source.getBigInteger() ).isEqualTo( new BigDecimal( "14" ) ); } - @Test + @ProcessorTest + @WithClasses({ BigDecimalOptionalSource.class, BigDecimalTarget.class, BigDecimalOptionalMapper.class }) + public void shouldApplyOptionalBigDecimalConversions() { + BigDecimalOptionalSource source = new BigDecimalOptionalSource(); + source.setB( Optional.of( new BigDecimal( "1.45" ) ) ); + source.setBb( Optional.of( new BigDecimal( "2.45" ) ) ); + source.setS( Optional.of( new BigDecimal( "3.45" ) ) ); + source.setSs( Optional.of( new BigDecimal( "4.45" ) ) ); + source.setI( Optional.of( new BigDecimal( "5.45" ) ) ); + source.setIi( Optional.of( new BigDecimal( "6.45" ) ) ); + source.setL( Optional.of( new BigDecimal( "7.45" ) ) ); + source.setLl( Optional.of( new BigDecimal( "8.45" ) ) ); + source.setF( Optional.of( new BigDecimal( "9.45" ) ) ); + source.setFf( Optional.of( new BigDecimal( "10.45" ) ) ); + source.setD( Optional.of( new BigDecimal( "11.45" ) ) ); + source.setDd( Optional.of( new BigDecimal( "12.45" ) ) ); + source.setString( Optional.of( new BigDecimal( "13.45" ) ) ); + source.setBigInteger( Optional.of( new BigDecimal( "14.45" ) ) ); + + BigDecimalTarget target = BigDecimalOptionalMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( (byte) 2 ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( (short) 4 ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( 6 ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( 8 ); + assertThat( target.getF() ).isEqualTo( 9.45f ); + assertThat( target.getFf() ).isEqualTo( 10.45f ); + assertThat( target.getD() ).isEqualTo( 11.45d ); + assertThat( target.getDd() ).isEqualTo( 12.45d ); + assertThat( target.getString() ).isEqualTo( "13.45" ); + assertThat( target.getBigInteger() ).isEqualTo( new BigInteger( "14" ) ); + } + + @ProcessorTest + @WithClasses({ BigDecimalOptionalSource.class, BigDecimalTarget.class, BigDecimalOptionalMapper.class }) + public void shouldApplyReverseOptionalBigDecimalConversions() { + BigDecimalTarget target = new BigDecimalTarget(); + target.setB( (byte) 1 ); + target.setBb( (byte) 2 ); + target.setS( (short) 3 ); + target.setSs( (short) 4 ); + target.setI( 5 ); + target.setIi( 6 ); + target.setL( 7 ); + target.setLl( 8L ); + target.setF( 9.0f ); + target.setFf( 10.0f ); + target.setD( 11.0d ); + target.setDd( 12.0d ); + target.setString( "13.45" ); + target.setBigInteger( new BigInteger( "14" ) ); + + BigDecimalOptionalSource source = BigDecimalOptionalMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getB() ).contains( new BigDecimal( "1" ) ); + assertThat( source.getBb() ).contains( new BigDecimal( "2" ) ); + assertThat( source.getS() ).contains( new BigDecimal( "3" ) ); + assertThat( source.getSs() ).contains( new BigDecimal( "4" ) ); + assertThat( source.getI() ).contains( new BigDecimal( "5" ) ); + assertThat( source.getIi() ).contains( new BigDecimal( "6" ) ); + assertThat( source.getL() ).contains( new BigDecimal( "7" ) ); + assertThat( source.getLl() ).contains( new BigDecimal( "8" ) ); + assertThat( source.getF() ).contains( new BigDecimal( "9.0" ) ); + assertThat( source.getFf() ).contains( new BigDecimal( "10.0" ) ); + assertThat( source.getD() ).contains( new BigDecimal( "11.0" ) ); + assertThat( source.getDd() ).contains( new BigDecimal( "12.0" ) ); + assertThat( source.getString() ).contains( new BigDecimal( "13.45" ) ); + assertThat( source.getBigInteger() ).contains( new BigDecimal( "14" ) ); + } + + @ProcessorTest @IssueKey("1009") @WithClasses({ BigIntegerSource.class, BigIntegerTarget.class, BigIntegerMapper.class }) public void shouldNotGenerateCreateDecimalFormatMethod() { - getGeneratedSource().forMapper( BigIntegerMapper.class ).content().doesNotContain( "createDecimalFormat" ); + generatedSource.forMapper( BigIntegerMapper.class ).content().doesNotContain( "createDecimalFormat" ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyConversionTest.java index 190ce76234..57b4f7e4e4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyConversionTest.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.currency; @@ -22,12 +9,10 @@ import java.util.HashSet; import java.util.Set; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.internal.util.Collections; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -36,14 +21,13 @@ */ @WithClasses({ CurrencyMapper.class, CurrencySource.class, CurrencyTarget.class }) @IssueKey("1355") -@RunWith(AnnotationProcessorTestRunner.class) public class CurrencyConversionTest { - @Test + @ProcessorTest public void shouldApplyCurrencyConversions() { final CurrencySource source = new CurrencySource(); source.setCurrencyA( Currency.getInstance( "USD" ) ); - Set currencies = new HashSet(); + Set currencies = new HashSet<>(); currencies.add( Currency.getInstance( "EUR" ) ); currencies.add( Currency.getInstance( "CHF" ) ); source.setUniqueCurrencies( currencies ); @@ -57,7 +41,7 @@ public void shouldApplyCurrencyConversions() { .containsExactlyInAnyOrder( "EUR", "CHF" ); } - @Test + @ProcessorTest public void shouldApplyReverseConversions() { final CurrencyTarget target = new CurrencyTarget(); target.setCurrencyA( "USD" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyMapper.java index 8c0b916d1c..eae0e41bcd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.currency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencySource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencySource.java index b9b2b0149f..a7a9408b98 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencySource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencySource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.currency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyTarget.java index dcf29ba691..384decb106 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/currency/CurrencyTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.currency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/DateConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/DateConversionTest.java index 8441510fdd..346f34a054 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/DateConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/DateConversionTest.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.date; -import static org.assertj.core.api.Assertions.assertThat; - import java.sql.Time; import java.sql.Timestamp; import java.util.Arrays; @@ -27,14 +12,14 @@ import java.util.Date; import java.util.GregorianCalendar; import java.util.List; -import java.util.Locale; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.DefaultLocale; +import org.junitpioneer.jupiter.ReadsDefaultTimeZone; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests application of format strings for conversions between strings and dates. @@ -47,46 +32,72 @@ SourceTargetMapper.class }) @IssueKey("43") -@RunWith(AnnotationProcessorTestRunner.class) +@DefaultLocale("de") +@ReadsDefaultTimeZone public class DateConversionTest { - @Before - public void setDefaultLocale() { - Locale.setDefault( Locale.GERMAN ); - } - - @Test - public void shouldApplyDateFormatForConversions() { + @ProcessorTest + public void shouldApplyDateFormatForConversionsJdk11() { Source source = new Source(); - source.setDate( new GregorianCalendar( 2013, 6, 6 ).getTime() ); - source.setAnotherDate( new GregorianCalendar( 2013, 1, 14 ).getTime() ); + source.setDate( new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime() ); + source.setAnotherDate( new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime() ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); assertThat( target ).isNotNull(); assertThat( target.getDate() ).isEqualTo( "06.07.2013" ); - assertThat( target.getAnotherDate() ).isEqualTo( "14.02.13 00:00" ); + assertThat( target.getAnotherDate() ).isEqualTo( "14.02.13, 00:00" ); + } + + @ProcessorTest + public void shouldApplyDateFormatForConversionsJdk11WithCustomLocale() { + Source source = new Source(); + source.setDate( new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime() ); + source.setAnotherDate( new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime() ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTargetWithCustomLocale( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getDate() ).isEqualTo( "juillet 06, 2013" ); + assertThat( target.getAnotherDate() ).isEqualTo( "14.02.13, 00:00" ); } - @Test - public void shouldApplyDateFormatForConversionInReverseMapping() { + @ProcessorTest + public void shouldApplyDateFormatForConversionInReverseMappingJdk11() { Target target = new Target(); target.setDate( "06.07.2013" ); - target.setAnotherDate( "14.02.13 8:30" ); + target.setAnotherDate( "14.02.13, 8:30" ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); assertThat( source ).isNotNull(); - assertThat( source.getDate() ).isEqualTo( new GregorianCalendar( 2013, 6, 6 ).getTime() ); - assertThat( source.getAnotherDate() ).isEqualTo( new GregorianCalendar( 2013, 1, 14, 8, 30 ).getTime() ); + assertThat( source.getDate() ).isEqualTo( new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime() ); + assertThat( source.getAnotherDate() ).isEqualTo( + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14, 8, 30 ).getTime() + ); } - @Test + @ProcessorTest + public void shouldApplyDateFormatForConversionInReverseMappingJdk11WithCustomLocale() { + Target target = new Target(); + target.setDate( "juillet 06, 2013" ); + target.setAnotherDate( "14.02.13, 8:30" ); + + Source source = SourceTargetMapper.INSTANCE.targetToSourceWithCustomLocale( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getDate() ).isEqualTo( new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime() ); + assertThat( source.getAnotherDate() ).isEqualTo( + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14, 8, 30 ).getTime() + ); + } + + @ProcessorTest public void shouldApplyStringConversionForIterableMethod() { List dates = Arrays.asList( - new GregorianCalendar( 2013, 6, 6 ).getTime(), - new GregorianCalendar( 2013, 1, 14 ).getTime(), - new GregorianCalendar( 2013, 3, 11 ).getTime() + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() ); List stringDates = SourceTargetMapper.INSTANCE.stringListToDateList( dates ); @@ -95,12 +106,26 @@ public void shouldApplyStringConversionForIterableMethod() { assertThat( stringDates ).containsExactly( "06.07.2013", "14.02.2013", "11.04.2013" ); } - @Test + @ProcessorTest + public void shouldApplyStringConversionForIterableMethodWithCustomLocale() { + List dates = Arrays.asList( + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() + ); + + List stringDates = SourceTargetMapper.INSTANCE.stringListToDateListWithCustomLocale( dates ); + + assertThat( stringDates ).isNotNull(); + assertThat( stringDates ).containsExactly( "juillet 06, 2013", "février 14, 2013", "avril 11, 2013" ); + } + + @ProcessorTest public void shouldApplyStringConversionForArrayMethod() { List dates = Arrays.asList( - new GregorianCalendar( 2013, 6, 6 ).getTime(), - new GregorianCalendar( 2013, 1, 14 ).getTime(), - new GregorianCalendar( 2013, 3, 11 ).getTime() + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() ); String[] stringDates = SourceTargetMapper.INSTANCE.stringListToDateArray( dates ); @@ -109,7 +134,21 @@ public void shouldApplyStringConversionForArrayMethod() { assertThat( stringDates ).isEqualTo( new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" } ); } - @Test + @ProcessorTest + public void shouldApplyStringConversionForArrayMethodWithCustomLocale() { + List dates = Arrays.asList( + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() + ); + + String[] stringDates = SourceTargetMapper.INSTANCE.stringListToDateArrayWithCustomLocale( dates ); + + assertThat( stringDates ).isNotNull(); + assertThat( stringDates ).isEqualTo( new String[]{ "juillet 06, 2013", "février 14, 2013", "avril 11, 2013" } ); + } + + @ProcessorTest public void shouldApplyStringConversionForReverseIterableMethod() { List stringDates = Arrays.asList( "06.07.2013", "14.02.2013", "11.04.2013" ); @@ -117,13 +156,27 @@ public void shouldApplyStringConversionForReverseIterableMethod() { assertThat( dates ).isNotNull(); assertThat( dates ).containsExactly( - new GregorianCalendar( 2013, 6, 6 ).getTime(), - new GregorianCalendar( 2013, 1, 14 ).getTime(), - new GregorianCalendar( 2013, 3, 11 ).getTime() + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() ); } - @Test + @ProcessorTest + public void shouldApplyStringConversionForReverseIterableMethodWithCustomLocale() { + List stringDates = Arrays.asList( "juillet 06, 2013", "février 14, 2013", "avril 11, 2013" ); + + List dates = SourceTargetMapper.INSTANCE.dateListToStringListWithCustomLocale( stringDates ); + + assertThat( dates ).isNotNull(); + assertThat( dates ).containsExactly( + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() + ); + } + + @ProcessorTest public void shouldApplyStringConversionForReverseArrayMethod() { String[] stringDates = new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" }; @@ -131,18 +184,32 @@ public void shouldApplyStringConversionForReverseArrayMethod() { assertThat( dates ).isNotNull(); assertThat( dates ).containsExactly( - new GregorianCalendar( 2013, 6, 6 ).getTime(), - new GregorianCalendar( 2013, 1, 14 ).getTime(), - new GregorianCalendar( 2013, 3, 11 ).getTime() + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() + ); + } + + @ProcessorTest + public void shouldApplyStringConversionForReverseArrayMethodWithCustomLocale() { + String[] stringDates = new String[]{ "juillet 06, 2013", "février 14, 2013", "avril 11, 2013" }; + + List dates = SourceTargetMapper.INSTANCE.stringArrayToDateListWithCustomLocale( stringDates ); + + assertThat( dates ).isNotNull(); + assertThat( dates ).containsExactly( + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() ); } - @Test + @ProcessorTest public void shouldApplyStringConversionForReverseArrayArrayMethod() { Date[] dates = new Date[]{ - new GregorianCalendar( 2013, 6, 6 ).getTime(), - new GregorianCalendar( 2013, 1, 14 ).getTime(), - new GregorianCalendar( 2013, 3, 11 ).getTime() + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() }; String[] stringDates = SourceTargetMapper.INSTANCE.dateArrayToStringArray( dates ); @@ -150,7 +217,7 @@ public void shouldApplyStringConversionForReverseArrayArrayMethod() { assertThat( stringDates ).isEqualTo( new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" } ); } - @Test + @ProcessorTest public void shouldApplyDateConversionForReverseArrayArrayMethod() { String[] stringDates = new String[]{ "06.07.2013", "14.02.2013", "11.04.2013" }; @@ -158,15 +225,15 @@ public void shouldApplyDateConversionForReverseArrayArrayMethod() { assertThat( dates ).isNotNull(); assertThat( dates ).isEqualTo( new Date[] { - new GregorianCalendar( 2013, 6, 6 ).getTime(), - new GregorianCalendar( 2013, 1, 14 ).getTime(), - new GregorianCalendar( 2013, 3, 11 ).getTime() + new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime(), + new GregorianCalendar( 2013, Calendar.FEBRUARY, 14 ).getTime(), + new GregorianCalendar( 2013, Calendar.APRIL, 11 ).getTime() } ); } @IssueKey("858") - @Test - public void shouldApplyDateToSqlConversion() throws Exception { + @ProcessorTest + public void shouldApplyDateToSqlConversion() { GregorianCalendar time = new GregorianCalendar( 2016, Calendar.AUGUST, 24, 20, 30, 30 ); GregorianCalendar sqlDate = new GregorianCalendar( 2016, Calendar.AUGUST, 23, 21, 35, 35 ); GregorianCalendar timestamp = new GregorianCalendar( 2016, Calendar.AUGUST, 22, 21, 35, 35 ); @@ -187,8 +254,8 @@ public void shouldApplyDateToSqlConversion() throws Exception { } @IssueKey("858") - @Test - public void shouldApplySqlToDateConversion() throws Exception { + @ProcessorTest + public void shouldApplySqlToDateConversion() { Target target = new Target(); GregorianCalendar time = new GregorianCalendar( 2016, Calendar.AUGUST, 24, 20, 30, 30 ); GregorianCalendar sqlDate = new GregorianCalendar( 2016, Calendar.AUGUST, 23, 21, 35, 35 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Source.java index eb20d26b82..619ddfb117 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.date; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/SourceTargetMapper.java index 75f4d0a52b..1971a8c066 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.date; @@ -35,21 +22,39 @@ public interface SourceTargetMapper { @Mapping(target = "date", dateFormat = "dd.MM.yyyy") Target sourceToTarget(Source source); - @InheritInverseConfiguration + @Mapping(target = "date", dateFormat = "MMMM dd, yyyy", locale = "fr") + Target sourceToTargetWithCustomLocale(Source source); + + @InheritInverseConfiguration(name = "sourceToTarget") Source targetToSource(Target target); + @InheritInverseConfiguration(name = "sourceToTargetWithCustomLocale") + Source targetToSourceWithCustomLocale(Target target); + @IterableMapping(dateFormat = "dd.MM.yyyy") List stringListToDateList(List dates); + @IterableMapping(dateFormat = "MMMM dd, yyyy", locale = "fr") + List stringListToDateListWithCustomLocale(List dates); + @IterableMapping(dateFormat = "dd.MM.yyyy") String[] stringListToDateArray(List dates); - @InheritInverseConfiguration + @IterableMapping(dateFormat = "MMMM dd, yyyy", locale = "fr") + String[] stringListToDateArrayWithCustomLocale(List dates); + + @InheritInverseConfiguration(name = "stringListToDateList") List dateListToStringList(List strings); - @InheritInverseConfiguration + @InheritInverseConfiguration(name = "stringListToDateListWithCustomLocale") + List dateListToStringListWithCustomLocale(List strings); + + @InheritInverseConfiguration(name = "stringListToDateArray") List stringArrayToDateList(String[] dates); + @InheritInverseConfiguration(name = "stringListToDateArrayWithCustomLocale") + List stringArrayToDateListWithCustomLocale(String[] dates); + @IterableMapping(dateFormat = "dd.MM.yyyy") String[] dateArrayToStringArray(Date[] dates); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Target.java index 263b12d46a..745c599bd0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/date/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.date; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/ErroneousFormatMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/ErroneousFormatMapper.java index 7f059125d0..bee6db6345 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/ErroneousFormatMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/ErroneousFormatMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/InvalidDateFormatTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/InvalidDateFormatTest.java index 09c4ad2c3e..81bf3eb568 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/InvalidDateFormatTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/InvalidDateFormatTest.java @@ -1,31 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.erroneous; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJoda; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -34,8 +20,8 @@ Source.class, Target.class }) +@WithJoda @IssueKey("725") -@RunWith(AnnotationProcessorTestRunner.class) public class InvalidDateFormatTest { @WithClasses({ @@ -45,54 +31,54 @@ public class InvalidDateFormatTest { diagnostics = { @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 38, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\""), + line = 25, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 39, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"\\."), + line = 26, + message = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 40, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"\\."), + line = 27, + message = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 41, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"\\."), + line = 28, + message = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 42, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"\\."), + line = 29, + message = "Given date format \"qwertz\" is invalid. Message: \"Unknown pattern letter: r\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 43, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\""), + line = 30, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 44, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\""), + line = 31, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 45, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\""), + line = 32, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 46, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\""), + line = 33, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern component: q\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 50, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\""), + line = 37, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 53, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\""), + line = 40, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\"."), @Diagnostic(type = ErroneousFormatMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 56, - messageRegExp = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\"") + line = 43, + message = "Given date format \"qwertz\" is invalid. Message: \"Illegal pattern character 'q'\".") }) - @Test + @ProcessorTest public void shouldFailWithInvalidDateFormats() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Source.java index 8614d1d6d2..4018fc1258 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Target.java index a6a71b8fdd..abaf46db7b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/erroneous/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8CustomPatternDateTimeFormatterGeneratedTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8CustomPatternDateTimeFormatterGeneratedTest.java new file mode 100644 index 0000000000..443de8aab5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8CustomPatternDateTimeFormatterGeneratedTest.java @@ -0,0 +1,53 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time; + +import java.time.LocalDateTime; +import java.time.Month; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.conversion.java8time.custompatterndatetimeformattergenerated.Source; +import org.mapstruct.ap.test.conversion.java8time.custompatterndatetimeformattergenerated.SourceTargetMapper; +import org.mapstruct.ap.test.conversion.java8time.custompatterndatetimeformattergenerated.Target; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests generation of DateTimeFormatters as mapper instance fields for conversions to/from Java 8 date and time types. + */ +@WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) +@IssueKey("2329") +public class Java8CustomPatternDateTimeFormatterGeneratedTest { + + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( SourceTargetMapper.class ); + + @ProcessorTest + public void testDateTimeFormattersGenerated() { + + Source source = new Source(); + source.setLocalDateTime1( LocalDateTime.of( 2021, Month.MAY, 16, 12, 13, 10 ) ); + source.setLocalDateTime2( LocalDateTime.of( 2020, Month.APRIL, 10, 15, 10, 12 ) ); + source.setLocalDateTime3( LocalDateTime.of( 2021, Month.APRIL, 25, 9, 46, 13 ) ); + + Target target = SourceTargetMapper.INSTANCE.map( source ); + + assertThat( target.getLocalDateTime1() ).isEqualTo( "16.05.2021 12:13" ); + assertThat( target.getLocalDateTime2() ).isEqualTo( "10.04.2020 15:10" ); + assertThat( target.getLocalDateTime3() ).isEqualTo( "25.04.2021 09.46" ); + + source = SourceTargetMapper.INSTANCE.map( target ); + + assertThat( source.getLocalDateTime1() ).isEqualTo( LocalDateTime.of( 2021, Month.MAY, 16, 12, 13, 0 ) ); + assertThat( source.getLocalDateTime2() ).isEqualTo( LocalDateTime.of( 2020, Month.APRIL, 10, 15, 10, 0 ) ); + assertThat( source.getLocalDateTime3() ).isEqualTo( LocalDateTime.of( 2021, Month.APRIL, 25, 9, 46, 0 ) ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8OptionalTimeConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8OptionalTimeConversionTest.java new file mode 100644 index 0000000000..1a9bb50b67 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8OptionalTimeConversionTest.java @@ -0,0 +1,466 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time; + +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Period; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; +import java.util.Optional; +import java.util.TimeZone; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junitpioneer.jupiter.DefaultTimeZone; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for conversions to/from Java 8 date and time types wrapped in {@link Optional}. + */ +@WithClasses({ OptionalSource.class, Target.class, OptionalSourceTargetMapper.class }) +public class Java8OptionalTimeConversionTest { + + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + void generatedCode() { + generatedSource.addComparisonToFixtureFor( OptionalSourceTargetMapper.class ); + } + + @ProcessorTest + public void testDateTimeToString() { + OptionalSource src = new OptionalSource(); + src.setZonedDateTime( Optional.of( ZonedDateTime.of( + LocalDateTime.of( 2014, 1, 1, 0, 0 ), + ZoneId.of( "UTC" ) + ) ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDateTimeMapped( src ); + assertThat( target ).isNotNull(); + assertThat( target.getZonedDateTime() ).isEqualTo( "01.01.2014 00:00 UTC" ); + } + + @ProcessorTest + public void testLocalDateTimeToString() { + OptionalSource src = new OptionalSource(); + src.setLocalDateTime( Optional.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetLocalDateTimeMapped( src ); + assertThat( target ).isNotNull(); + assertThat( target.getLocalDateTime() ).isEqualTo( "01.01.2014 00:00" ); + } + + @ProcessorTest + public void testLocalDateToString() { + OptionalSource src = new OptionalSource(); + src.setLocalDate( Optional.of( LocalDate.of( 2014, 1, 1 ) ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetLocalDateMapped( src ); + assertThat( target ).isNotNull(); + assertThat( target.getLocalDate() ).isEqualTo( "01.01.2014" ); + } + + @ProcessorTest + public void testLocalTimeToString() { + OptionalSource src = new OptionalSource(); + src.setLocalTime( Optional.ofNullable( LocalTime.of( 0, 0 ) ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetLocalTimeMapped( src ); + assertThat( target ).isNotNull(); + assertThat( target.getLocalTime() ).isEqualTo( "00:00" ); + } + + @ProcessorTest + public void testSourceToTargetMappingForStrings() { + OptionalSource src = new OptionalSource(); + src.setLocalTime( Optional.ofNullable( LocalTime.of( 0, 0 ) ) ); + src.setLocalDate( Optional.of( LocalDate.of( 2014, 1, 1 ) ) ); + src.setLocalDateTime( Optional.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ) ); + src.setZonedDateTime( Optional.of( ZonedDateTime.of( + LocalDateTime.of( 2014, 1, 1, 0, 0 ), + ZoneId.of( "UTC" ) + ) ) ); + + // with given format + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( src ); + + assertThat( target ).isNotNull(); + assertThat( target.getZonedDateTime() ).isEqualTo( "01.01.2014 00:00 UTC" ); + assertThat( target.getLocalDateTime() ).isEqualTo( "01.01.2014 00:00" ); + assertThat( target.getLocalDate() ).isEqualTo( "01.01.2014" ); + assertThat( target.getLocalTime() ).isEqualTo( "00:00" ); + + // and now with default mappings + target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( src ); + assertThat( target ).isNotNull(); + assertThat( target.getZonedDateTime() ).isEqualTo( "01.01.2014 00:00 UTC" ); + assertThat( target.getLocalDateTime() ).isEqualTo( "01.01.2014 00:00" ); + assertThat( target.getLocalDate() ).isEqualTo( "01.01.2014" ); + assertThat( target.getLocalTime() ).isEqualTo( "00:00" ); + } + + @ProcessorTest + public void testStringToDateTime() { + String dateTimeAsString = "01.01.2014 00:00 UTC"; + Target target = new Target(); + target.setZonedDateTime( dateTimeAsString ); + ZonedDateTime sourceDateTime = + ZonedDateTime.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); + + OptionalSource src = OptionalSourceTargetMapper.INSTANCE.targetToSourceDateTimeMapped( target ); + assertThat( src ).isNotNull(); + assertThat( src.getZonedDateTime() ).contains( sourceDateTime ); + } + + @ProcessorTest + public void testStringToLocalDateTime() { + String dateTimeAsString = "01.01.2014 00:00"; + Target target = new Target(); + target.setLocalDateTime( dateTimeAsString ); + LocalDateTime sourceDateTime = + LocalDateTime.of( 2014, 1, 1, 0, 0, 0 ); + + OptionalSource src = OptionalSourceTargetMapper.INSTANCE.targetToSourceLocalDateTimeMapped( target ); + assertThat( src ).isNotNull(); + assertThat( src.getLocalDateTime() ).contains( sourceDateTime ); + } + + @ProcessorTest + public void testStringToLocalDate() { + String dateTimeAsString = "01.01.2014"; + Target target = new Target(); + target.setLocalDate( dateTimeAsString ); + LocalDate sourceDate = + LocalDate.of( 2014, 1, 1 ); + + OptionalSource src = OptionalSourceTargetMapper.INSTANCE.targetToSourceLocalDateMapped( target ); + assertThat( src ).isNotNull(); + assertThat( src.getLocalDate() ).contains( sourceDate ); + } + + @ProcessorTest + public void testStringToLocalTime() { + String dateTimeAsString = "00:00"; + Target target = new Target(); + target.setLocalTime( dateTimeAsString ); + LocalTime sourceTime = + LocalTime.of( 0, 0 ); + + OptionalSource src = OptionalSourceTargetMapper.INSTANCE.targetToSourceLocalTimeMapped( target ); + assertThat( src ).isNotNull(); + assertThat( src.getLocalTime() ).contains( sourceTime ); + } + + @ProcessorTest + public void testTargetToSourceNullMapping() { + Target target = new Target(); + OptionalSource src = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( src ).isNotNull(); + assertThat( src.getZonedDateTime() ).isEmpty(); + assertThat( src.getLocalDate() ).isEmpty(); + assertThat( src.getLocalDateTime() ).isEmpty(); + assertThat( src.getLocalTime() ).isEmpty(); + } + + @ProcessorTest + public void testTargetToSourceMappingForStrings() { + Target target = new Target(); + + target.setZonedDateTime( "01.01.2014 00:00 UTC" ); + target.setLocalDateTime( "01.01.2014 00:00" ); + target.setLocalDate( "01.01.2014" ); + target.setLocalTime( "00:00" ); + + OptionalSource src = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( src.getZonedDateTime() ).contains( + ZonedDateTime.of( + LocalDateTime.of( + 2014, + 1, + 1, + 0, + 0 + ), ZoneId.of( "UTC" ) + ) ); + assertThat( src.getLocalDateTime() ).contains( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ); + assertThat( src.getLocalDate() ).contains( LocalDate.of( 2014, 1, 1 ) ); + assertThat( src.getLocalTime() ).contains( LocalTime.of( 0, 0 ) ); + } + + @ProcessorTest + public void testCalendarMapping() { + OptionalSource source = new OptionalSource(); + ZonedDateTime dateTime = ZonedDateTime.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); + source.setForCalendarConversion( Optional.of( dateTime ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target.getForCalendarConversion() ).isNotNull(); + assertThat( target.getForCalendarConversion().getTimeZone() ).isEqualTo( + TimeZone.getTimeZone( + "UTC" ) ); + assertThat( target.getForCalendarConversion().get( Calendar.YEAR ) ).isEqualTo( dateTime.getYear() ); + assertThat( target.getForCalendarConversion().get( Calendar.MONTH ) ).isEqualTo( + dateTime.getMonthValue() - 1 ); + assertThat( target.getForCalendarConversion().get( Calendar.DATE ) ).isEqualTo( dateTime.getDayOfMonth() ); + assertThat( target.getForCalendarConversion().get( Calendar.MINUTE ) ).isEqualTo( dateTime.getMinute() ); + assertThat( target.getForCalendarConversion().get( Calendar.HOUR ) ).isEqualTo( dateTime.getHour() ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source.getForCalendarConversion() ).contains( dateTime ); + } + + @ProcessorTest + @DefaultTimeZone("UTC") + public void testZonedDateTimeToDateMapping() { + OptionalSource source = new OptionalSource(); + ZonedDateTime dateTime = ZonedDateTime.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); + source.setForDateConversionWithZonedDateTime( Optional.of( dateTime ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + + assertThat( target.getForDateConversionWithZonedDateTime() ).isNotNull(); + + Calendar instance = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); + instance.setTimeInMillis( target.getForDateConversionWithZonedDateTime().getTime() ); + + assertThat( instance.get( Calendar.YEAR ) ).isEqualTo( dateTime.getYear() ); + assertThat( instance.get( Calendar.MONTH ) ).isEqualTo( dateTime.getMonthValue() - 1 ); + assertThat( instance.get( Calendar.DATE ) ).isEqualTo( dateTime.getDayOfMonth() ); + assertThat( instance.get( Calendar.MINUTE ) ).isEqualTo( dateTime.getMinute() ); + assertThat( instance.get( Calendar.HOUR ) ).isEqualTo( dateTime.getHour() ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source.getForDateConversionWithZonedDateTime() ).contains( dateTime ); + } + + @ProcessorTest + public void testInstantToDateMapping() { + Instant instant = Instant.ofEpochMilli( 1539366615000L ); + + OptionalSource source = new OptionalSource(); + source.setForDateConversionWithInstant( Optional.ofNullable( instant ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + Date date = target.getForDateConversionWithInstant(); + assertThat( date ).isNotNull(); + assertThat( date.getTime() ).isEqualTo( 1539366615000L ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForDateConversionWithInstant() ).contains( instant ); + } + + @ProcessorTest + public void testLocalDateTimeToLocalDateMapping() { + LocalDate localDate = LocalDate.of( 2014, 1, 1 ); + + OptionalSource source = new OptionalSource(); + source.setForLocalDateTimeConversionWithLocalDate( Optional.of( localDate ) ); + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + LocalDateTime localDateTime = target.getForLocalDateTimeConversionWithLocalDate(); + assertThat( localDateTime ).isNotNull(); + assertThat( localDateTime ).isEqualTo( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForLocalDateTimeConversionWithLocalDate() ).contains( localDate ); + } + + @ProcessorTest + @DefaultTimeZone("Australia/Melbourne") + public void testLocalDateTimeToDateMapping() { + + OptionalSource source = new OptionalSource(); + LocalDateTime dateTime = LocalDateTime.of( 2014, 1, 1, 0, 0 ); + source.setForDateConversionWithLocalDateTime( Optional.of( dateTime ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + + assertThat( target.getForDateConversionWithLocalDateTime() ).isNotNull(); + + Calendar instance = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); + instance.setTimeInMillis( target.getForDateConversionWithLocalDateTime().getTime() ); + + assertThat( instance.get( Calendar.YEAR ) ).isEqualTo( dateTime.getYear() ); + assertThat( instance.get( Calendar.MONTH ) ).isEqualTo( dateTime.getMonthValue() - 1 ); + assertThat( instance.get( Calendar.DATE ) ).isEqualTo( dateTime.getDayOfMonth() ); + assertThat( instance.get( Calendar.MINUTE ) ).isEqualTo( dateTime.getMinute() ); + assertThat( instance.get( Calendar.HOUR ) ).isEqualTo( dateTime.getHour() ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source.getForDateConversionWithLocalDateTime() ).contains( dateTime ); + } + + @ProcessorTest + @DefaultTimeZone("Australia/Melbourne") + public void testLocalDateToDateMapping() { + + OptionalSource source = new OptionalSource(); + LocalDate localDate = LocalDate.of( 2016, 3, 1 ); + source.setForDateConversionWithLocalDate( Optional.of( localDate ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + + assertThat( target.getForDateConversionWithLocalDate() ).isNotNull(); + + Calendar instance = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); + instance.setTimeInMillis( target.getForDateConversionWithLocalDate().getTime() ); + + assertThat( instance.get( Calendar.YEAR ) ).isEqualTo( localDate.getYear() ); + assertThat( instance.get( Calendar.MONTH ) ).isEqualTo( localDate.getMonthValue() - 1 ); + assertThat( instance.get( Calendar.DATE ) ).isEqualTo( localDate.getDayOfMonth() ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source.getForDateConversionWithLocalDate() ).contains( localDate ); + } + + @ProcessorTest + @DefaultTimeZone("Australia/Melbourne") + public void testLocalDateToSqlDateMapping() { + + OptionalSource source = new OptionalSource(); + LocalDate localDate = LocalDate.of( 2016, 3, 1 ); + source.setForSqlDateConversionWithLocalDate( Optional.of( localDate ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + + assertThat( target.getForSqlDateConversionWithLocalDate() ).isNotNull(); + + Calendar instance = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); + instance.setTimeInMillis( target.getForSqlDateConversionWithLocalDate().getTime() ); + + assertThat( instance.get( Calendar.YEAR ) ).isEqualTo( localDate.getYear() ); + assertThat( instance.get( Calendar.MONTH ) ).isEqualTo( localDate.getMonthValue() - 1 ); + assertThat( instance.get( Calendar.DATE ) ).isEqualTo( localDate.getDayOfMonth() ); + + source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source.getForSqlDateConversionWithLocalDate() ).contains( localDate ); + } + + @ProcessorTest + public void testInstantToStringMapping() { + OptionalSource source = new OptionalSource(); + source.setForInstantConversionWithString( Optional.ofNullable( Instant.ofEpochSecond( 42L ) ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForInstantConversionWithString(); + assertThat( periodString ).isEqualTo( "1970-01-01T00:00:42Z" ); + } + + @ProcessorTest + public void testInstantToStringNullMapping() { + OptionalSource source = new OptionalSource(); + source.setForInstantConversionWithString( Optional.empty() ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForInstantConversionWithString(); + assertThat( periodString ).isNull(); + } + + @ProcessorTest + public void testStringToInstantMapping() { + Target target = new Target(); + target.setForInstantConversionWithString( "1970-01-01T00:00:00.000Z" ); + + OptionalSource source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForInstantConversionWithString() ).contains( Instant.EPOCH ); + } + + @ProcessorTest + public void testStringToInstantNullMapping() { + Target target = new Target(); + target.setForInstantConversionWithString( null ); + + OptionalSource source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForInstantConversionWithString() ).isEmpty(); + } + + @ProcessorTest + public void testPeriodToStringMapping() { + OptionalSource source = new OptionalSource(); + source.setForPeriodConversionWithString( Optional.ofNullable( Period.ofDays( 42 ) ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForPeriodConversionWithString(); + assertThat( periodString ).isEqualTo( "P42D" ); + } + + @ProcessorTest + public void testPeriodToStringNullMapping() { + OptionalSource source = new OptionalSource(); + source.setForPeriodConversionWithString( Optional.empty() ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForPeriodConversionWithString(); + assertThat( periodString ).isNull(); + } + + @ProcessorTest + public void testStringToPeriodMapping() { + Target target = new Target(); + target.setForPeriodConversionWithString( "P1Y2M3D" ); + + OptionalSource source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForPeriodConversionWithString() ).contains( Period.of( 1, 2, 3 ) ); + } + + @ProcessorTest + public void testStringToPeriodNullMapping() { + Target target = new Target(); + target.setForPeriodConversionWithString( null ); + + OptionalSource source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForPeriodConversionWithString() ).isEmpty(); + } + + @ProcessorTest + public void testDurationToStringMapping() { + OptionalSource source = new OptionalSource(); + source.setForDurationConversionWithString( Optional.ofNullable( Duration.ofMinutes( 42L ) ) ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + String durationString = target.getForDurationConversionWithString(); + assertThat( durationString ).isEqualTo( "PT42M" ); + } + + @ProcessorTest + public void testDurationToStringNullMapping() { + OptionalSource source = new OptionalSource(); + source.setForDurationConversionWithString( Optional.empty() ); + + Target target = OptionalSourceTargetMapper.INSTANCE.sourceToTarget( source ); + String durationString = target.getForDurationConversionWithString(); + assertThat( durationString ).isNull(); + } + + @ProcessorTest + public void testStringToDurationMapping() { + Target target = new Target(); + target.setForDurationConversionWithString( "PT20.345S" ); + + OptionalSource source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForDurationConversionWithString() ).contains( Duration.ofSeconds( 20L, 345000000L ) ); + } + + @ProcessorTest + public void testStringToDurationNullMapping() { + Target target = new Target(); + target.setForDurationConversionWithString( null ); + + OptionalSource source = OptionalSourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForDurationConversionWithString() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8TimeConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8TimeConversionTest.java index 7e7574d1ba..4eab59fbe3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8TimeConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Java8TimeConversionTest.java @@ -1,48 +1,42 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time; -import static org.assertj.core.api.Assertions.assertThat; - +import java.time.Duration; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Period; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.Calendar; +import java.util.Date; import java.util.TimeZone; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junitpioneer.jupiter.DefaultTimeZone; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests for conversions to/from Java 8 date and time types. */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) @IssueKey("121") public class Java8TimeConversionTest { - @Test + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( SourceTargetMapper.class ); + + @ProcessorTest public void testDateTimeToString() { Source src = new Source(); src.setZonedDateTime( ZonedDateTime.of( java.time.LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ) ); @@ -51,7 +45,7 @@ public void testDateTimeToString() { assertThat( target.getZonedDateTime() ).isEqualTo( "01.01.2014 00:00 UTC" ); } - @Test + @ProcessorTest public void testLocalDateTimeToString() { Source src = new Source(); src.setLocalDateTime( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ); @@ -60,7 +54,7 @@ public void testLocalDateTimeToString() { assertThat( target.getLocalDateTime() ).isEqualTo( "01.01.2014 00:00" ); } - @Test + @ProcessorTest public void testLocalDateToString() { Source src = new Source(); src.setLocalDate( LocalDate.of( 2014, 1, 1 ) ); @@ -69,7 +63,7 @@ public void testLocalDateToString() { assertThat( target.getLocalDate() ).isEqualTo( "01.01.2014" ); } - @Test + @ProcessorTest public void testLocalTimeToString() { Source src = new Source(); src.setLocalTime( LocalTime.of( 0, 0 ) ); @@ -78,7 +72,7 @@ public void testLocalTimeToString() { assertThat( target.getLocalTime() ).isEqualTo( "00:00" ); } - @Test + @ProcessorTest public void testSourceToTargetMappingForStrings() { Source src = new Source(); src.setLocalTime( LocalTime.of( 0, 0 ) ); @@ -104,59 +98,59 @@ public void testSourceToTargetMappingForStrings() { assertThat( target.getLocalTime() ).isEqualTo( "00:00" ); } - @Test + @ProcessorTest public void testStringToDateTime() { String dateTimeAsString = "01.01.2014 00:00 UTC"; Target target = new Target(); target.setZonedDateTime( dateTimeAsString ); ZonedDateTime sourceDateTime = - ZonedDateTime.of( java.time.LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); + ZonedDateTime.of( java.time.LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); Source src = SourceTargetMapper.INSTANCE.targetToSourceDateTimeMapped( target ); assertThat( src ).isNotNull(); assertThat( src.getZonedDateTime() ).isEqualTo( sourceDateTime ); } - @Test + @ProcessorTest public void testStringToLocalDateTime() { String dateTimeAsString = "01.01.2014 00:00"; Target target = new Target(); target.setLocalDateTime( dateTimeAsString ); LocalDateTime sourceDateTime = - LocalDateTime.of( 2014, 1, 1, 0, 0, 0 ); + LocalDateTime.of( 2014, 1, 1, 0, 0, 0 ); Source src = SourceTargetMapper.INSTANCE.targetToSourceLocalDateTimeMapped( target ); assertThat( src ).isNotNull(); assertThat( src.getLocalDateTime() ).isEqualTo( sourceDateTime ); } - @Test + @ProcessorTest public void testStringToLocalDate() { String dateTimeAsString = "01.01.2014"; Target target = new Target(); target.setLocalDate( dateTimeAsString ); LocalDate sourceDate = - LocalDate.of( 2014, 1, 1 ); + LocalDate.of( 2014, 1, 1 ); Source src = SourceTargetMapper.INSTANCE.targetToSourceLocalDateMapped( target ); assertThat( src ).isNotNull(); assertThat( src.getLocalDate() ).isEqualTo( sourceDate ); } - @Test + @ProcessorTest public void testStringToLocalTime() { String dateTimeAsString = "00:00"; Target target = new Target(); target.setLocalTime( dateTimeAsString ); LocalTime sourceTime = - LocalTime.of( 0, 0 ); + LocalTime.of( 0, 0 ); Source src = SourceTargetMapper.INSTANCE.targetToSourceLocalTimeMapped( target ); assertThat( src ).isNotNull(); assertThat( src.getLocalTime() ).isEqualTo( sourceTime ); } - @Test + @ProcessorTest public void testTargetToSourceNullMapping() { Target target = new Target(); Source src = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -168,7 +162,7 @@ public void testTargetToSourceNullMapping() { assertThat( src.getLocalTime() ).isNull(); } - @Test + @ProcessorTest public void testTargetToSourceMappingForStrings() { Target target = new Target(); @@ -180,34 +174,35 @@ public void testTargetToSourceMappingForStrings() { Source src = SourceTargetMapper.INSTANCE.targetToSource( target ); assertThat( src.getZonedDateTime() ).isEqualTo( - ZonedDateTime.of( - java.time.LocalDateTime.of( - 2014, - 1, - 1, - 0, - 0 ), ZoneId.of( "UTC" ) ) ); + ZonedDateTime.of( + java.time.LocalDateTime.of( + 2014, + 1, + 1, + 0, + 0 + ), ZoneId.of( "UTC" ) ) ); assertThat( src.getLocalDateTime() ).isEqualTo( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ); assertThat( src.getLocalDate() ).isEqualTo( LocalDate.of( 2014, 1, 1 ) ); assertThat( src.getLocalTime() ).isEqualTo( LocalTime.of( 0, 0 ) ); } - @Test + @ProcessorTest public void testCalendarMapping() { Source source = new Source(); ZonedDateTime dateTime = ZonedDateTime.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); source.setForCalendarConversion( - dateTime ); + dateTime ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); assertThat( target.getForCalendarConversion() ).isNotNull(); assertThat( target.getForCalendarConversion().getTimeZone() ).isEqualTo( - TimeZone.getTimeZone( - "UTC" ) ); + TimeZone.getTimeZone( + "UTC" ) ); assertThat( target.getForCalendarConversion().get( Calendar.YEAR ) ).isEqualTo( dateTime.getYear() ); assertThat( target.getForCalendarConversion().get( Calendar.MONTH ) ).isEqualTo( - dateTime.getMonthValue() - 1 ); + dateTime.getMonthValue() - 1 ); assertThat( target.getForCalendarConversion().get( Calendar.DATE ) ).isEqualTo( dateTime.getDayOfMonth() ); assertThat( target.getForCalendarConversion().get( Calendar.MINUTE ) ).isEqualTo( dateTime.getMinute() ); assertThat( target.getForCalendarConversion().get( Calendar.HOUR ) ).isEqualTo( dateTime.getHour() ); @@ -217,13 +212,13 @@ public void testCalendarMapping() { assertThat( source.getForCalendarConversion() ).isEqualTo( dateTime ); } - @Test + @ProcessorTest + @DefaultTimeZone("UTC") public void testZonedDateTimeToDateMapping() { - TimeZone.setDefault( TimeZone.getTimeZone( "UTC" ) ); Source source = new Source(); ZonedDateTime dateTime = ZonedDateTime.of( LocalDateTime.of( 2014, 1, 1, 0, 0 ), ZoneId.of( "UTC" ) ); source.setForDateConversionWithZonedDateTime( - dateTime ); + dateTime ); Target target = SourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); assertThat( target.getForDateConversionWithZonedDateTime() ).isNotNull(); @@ -242,9 +237,39 @@ public void testZonedDateTimeToDateMapping() { assertThat( source.getForDateConversionWithZonedDateTime() ).isEqualTo( dateTime ); } - @Test + @ProcessorTest + public void testInstantToDateMapping() { + Instant instant = Instant.ofEpochMilli( 1539366615000L ); + + Source source = new Source(); + source.setForDateConversionWithInstant( instant ); + Target target = SourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + Date date = target.getForDateConversionWithInstant(); + assertThat( date ).isNotNull(); + assertThat( date.getTime() ).isEqualTo( 1539366615000L ); + + source = SourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForDateConversionWithInstant() ).isEqualTo( instant ); + } + + @ProcessorTest + public void testLocalDateTimeToLocalDateMapping() { + LocalDate localDate = LocalDate.of( 2014, 1, 1 ); + + Source source = new Source(); + source.setForLocalDateTimeConversionWithLocalDate( localDate ); + Target target = SourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + LocalDateTime localDateTime = target.getForLocalDateTimeConversionWithLocalDate(); + assertThat( localDateTime ).isNotNull(); + assertThat( localDateTime ).isEqualTo( LocalDateTime.of( 2014, 1, 1, 0, 0 ) ); + + source = SourceTargetMapper.INSTANCE.targetToSource( target ); + assertThat( source.getForLocalDateTimeConversionWithLocalDate() ).isEqualTo( localDate ); + } + + @ProcessorTest + @DefaultTimeZone("Australia/Melbourne") public void testLocalDateTimeToDateMapping() { - TimeZone.setDefault( TimeZone.getTimeZone( "Australia/Melbourne" ) ); Source source = new Source(); LocalDateTime dateTime = LocalDateTime.of( 2014, 1, 1, 0, 0 ); @@ -268,9 +293,9 @@ public void testLocalDateTimeToDateMapping() { assertThat( source.getForDateConversionWithLocalDateTime() ).isEqualTo( dateTime ); } - @Test + @ProcessorTest + @DefaultTimeZone("Australia/Melbourne") public void testLocalDateToDateMapping() { - TimeZone.setDefault( TimeZone.getTimeZone( "Australia/Melbourne" ) ); Source source = new Source(); LocalDate localDate = LocalDate.of( 2016, 3, 1 ); @@ -291,4 +316,148 @@ public void testLocalDateToDateMapping() { assertThat( source.getForDateConversionWithLocalDate() ).isEqualTo( localDate ); } + + @ProcessorTest + @DefaultTimeZone("Australia/Melbourne") + public void testLocalDateToSqlDateMapping() { + + Source source = new Source(); + LocalDate localDate = LocalDate.of( 2016, 3, 1 ); + source.setForSqlDateConversionWithLocalDate( localDate ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( source ); + + assertThat( target.getForSqlDateConversionWithLocalDate() ).isNotNull(); + + Calendar instance = Calendar.getInstance( TimeZone.getTimeZone( "UTC" ) ); + instance.setTimeInMillis( target.getForSqlDateConversionWithLocalDate().getTime() ); + + assertThat( instance.get( Calendar.YEAR ) ).isEqualTo( localDate.getYear() ); + assertThat( instance.get( Calendar.MONTH ) ).isEqualTo( localDate.getMonthValue() - 1 ); + assertThat( instance.get( Calendar.DATE ) ).isEqualTo( localDate.getDayOfMonth() ); + + source = SourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source.getForSqlDateConversionWithLocalDate() ).isEqualTo( localDate ); + } + + @ProcessorTest + public void testInstantToStringMapping() { + Source source = new Source(); + source.setForInstantConversionWithString( Instant.ofEpochSecond( 42L ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForInstantConversionWithString(); + assertThat( periodString ).isEqualTo( "1970-01-01T00:00:42Z" ); + } + + @ProcessorTest + public void testInstantToStringNullMapping() { + Source source = new Source(); + source.setForInstantConversionWithString( null ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForInstantConversionWithString(); + assertThat( periodString ).isNull(); + } + + @ProcessorTest + public void testStringToInstantMapping() { + Target target = new Target(); + target.setForInstantConversionWithString( "1970-01-01T00:00:00.000Z" ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + Instant instant = source.getForInstantConversionWithString(); + assertThat( instant ).isEqualTo( Instant.EPOCH ); + } + + @ProcessorTest + public void testStringToInstantNullMapping() { + Target target = new Target(); + target.setForInstantConversionWithString( null ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + Instant instant = source.getForInstantConversionWithString(); + assertThat( instant ).isNull(); + } + + @ProcessorTest + public void testPeriodToStringMapping() { + Source source = new Source(); + source.setForPeriodConversionWithString( Period.ofDays( 42 ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForPeriodConversionWithString(); + assertThat( periodString ).isEqualTo( "P42D" ); + } + + @ProcessorTest + public void testPeriodToStringNullMapping() { + Source source = new Source(); + source.setForPeriodConversionWithString( null ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + String periodString = target.getForPeriodConversionWithString(); + assertThat( periodString ).isNull(); + } + + @ProcessorTest + public void testStringToPeriodMapping() { + Target target = new Target(); + target.setForPeriodConversionWithString( "P1Y2M3D" ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + Period period = source.getForPeriodConversionWithString(); + assertThat( period ).isEqualTo( Period.of( 1, 2, 3 ) ); + } + + @ProcessorTest + public void testStringToPeriodNullMapping() { + Target target = new Target(); + target.setForPeriodConversionWithString( null ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + Period period = source.getForPeriodConversionWithString(); + assertThat( period ).isNull(); + } + + @ProcessorTest + public void testDurationToStringMapping() { + Source source = new Source(); + source.setForDurationConversionWithString( Duration.ofMinutes( 42L ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + String durationString = target.getForDurationConversionWithString(); + assertThat( durationString ).isEqualTo( "PT42M" ); + } + + @ProcessorTest + public void testDurationToStringNullMapping() { + Source source = new Source(); + source.setForDurationConversionWithString( null ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + String durationString = target.getForDurationConversionWithString(); + assertThat( durationString ).isNull(); + } + + @ProcessorTest + public void testStringToDurationMapping() { + Target target = new Target(); + target.setForDurationConversionWithString( "PT20.345S" ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + Duration duration = source.getForDurationConversionWithString(); + assertThat( duration ).isEqualTo( Duration.ofSeconds( 20L, 345000000L ) ); + } + + @ProcessorTest + public void testStringToDurationNullMapping() { + Target target = new Target(); + target.setForDurationConversionWithString( null ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + Duration duration = source.getForDurationConversionWithString(); + assertThat( duration ).isNull(); + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateTimeToXMLGregorianCalendarConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateTimeToXMLGregorianCalendarConversionTest.java new file mode 100644 index 0000000000..5f656f2f76 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateTimeToXMLGregorianCalendarConversionTest.java @@ -0,0 +1,116 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time; + +import java.time.LocalDateTime; +import java.util.Calendar; +import javax.xml.datatype.DatatypeConfigurationException; +import javax.xml.datatype.DatatypeConstants; +import javax.xml.datatype.DatatypeFactory; +import javax.xml.datatype.XMLGregorianCalendar; + +import org.mapstruct.ap.test.conversion.java8time.localdatetimetoxmlgregoriancalendarconversion.Source; +import org.mapstruct.ap.test.conversion.java8time.localdatetimetoxmlgregoriancalendarconversion.SourceTargetMapper; +import org.mapstruct.ap.test.conversion.java8time.localdatetimetoxmlgregoriancalendarconversion.Target; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Andrei Arlou + */ +@WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) +public class LocalDateTimeToXMLGregorianCalendarConversionTest { + + @ProcessorTest + public void shouldNullCheckOnConversionToTarget() { + Target target = SourceTargetMapper.INSTANCE.toTarget( new Source() ); + + assertThat( target ).isNotNull(); + assertThat( target.getLocalDateTime() ).isNull(); + } + + @ProcessorTest + public void shouldNullCheckOnConversionToSource() { + Source source = SourceTargetMapper.INSTANCE.toSource( new Target() ); + + assertThat( source ).isNotNull(); + assertThat( source.getXmlGregorianCalendar() ).isNull(); + } + + @ProcessorTest + public void shouldMapLocalDateTimeToXmlGregorianCalendarCorrectlyWithNanoseconds() + throws DatatypeConfigurationException { + LocalDateTime localDateTime = LocalDateTime.of( 1994, Calendar.MARCH, 5, 11, 30, 50, 9000000 ); + Target target = new Target(); + target.setLocalDateTime( localDateTime ); + + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + + XMLGregorianCalendar expectedCalendar = DatatypeFactory.newInstance() + .newXMLGregorianCalendar( 1994, Calendar.MARCH, 5, 11, 30, 50, 9, + DatatypeConstants.FIELD_UNDEFINED + ); + + assertThat( source ).isNotNull(); + assertThat( source.getXmlGregorianCalendar() ).isEqualTo( expectedCalendar ); + } + + @ProcessorTest + public void shouldMapLocalDateTimeToXmlGregorianCalendarCorrectlyWithSeconds() + throws DatatypeConfigurationException { + LocalDateTime localDateTime = LocalDateTime.of( 1994, Calendar.MARCH, 5, 11, 30, 50 ); + Target target = new Target(); + target.setLocalDateTime( localDateTime ); + + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + + XMLGregorianCalendar expectedCalendar = DatatypeFactory.newInstance() + .newXMLGregorianCalendar( 1994, Calendar.MARCH, 5, 11, 30, 50, 0, + DatatypeConstants.FIELD_UNDEFINED + ); + + assertThat( source ).isNotNull(); + assertThat( source.getXmlGregorianCalendar() ).isEqualTo( expectedCalendar ); + } + + @ProcessorTest + public void shouldMapLocalDateTimeToXmlGregorianCalendarCorrectlyWithMinutes() + throws DatatypeConfigurationException { + LocalDateTime localDateTime = LocalDateTime.of( 1994, Calendar.MARCH, 5, 11, 30 ); + Target target = new Target(); + target.setLocalDateTime( localDateTime ); + + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + + XMLGregorianCalendar expectedCalendar = DatatypeFactory.newInstance() + .newXMLGregorianCalendar( 1994, Calendar.MARCH, 5, 11, 30, 0, 0, + DatatypeConstants.FIELD_UNDEFINED + ); + + assertThat( source ).isNotNull(); + assertThat( source.getXmlGregorianCalendar() ).isEqualTo( expectedCalendar ); + } + + @ProcessorTest + public void shouldMapXmlGregorianCalendarToLocalDateTimeCorrectly() throws DatatypeConfigurationException { + XMLGregorianCalendar xmlGregorianCalendar = DatatypeFactory.newInstance() + .newXMLGregorianCalendar( 1994, Calendar.MARCH, 5, 11, 30, 50, 500, + DatatypeConstants.FIELD_UNDEFINED + ); + + Source source = new Source(); + source.setXmlGregorianCalendar( xmlGregorianCalendar ); + + Target target = SourceTargetMapper.INSTANCE.toTarget( source ); + + LocalDateTime expectedLocalDateTime = LocalDateTime.of( 1994, Calendar.MARCH, 5, 11, 30, 50, 500000000 ); + + assertThat( target ).isNotNull(); + assertThat( target.getLocalDateTime() ).isEqualTo( expectedLocalDateTime ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateToXMLGregorianCalendarConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateToXMLGregorianCalendarConversionTest.java index 9a76dd0aaf..935e12d55d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateToXMLGregorianCalendarConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/LocalDateToXMLGregorianCalendarConversionTest.java @@ -1,49 +1,32 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time; -import static org.assertj.core.api.Assertions.assertThat; - import java.time.LocalDate; - import javax.xml.datatype.DatatypeConstants; import javax.xml.datatype.DatatypeFactory; import javax.xml.datatype.XMLGregorianCalendar; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.conversion.java8time.localdatetoxmlgregoriancalendarconversion.Source; import org.mapstruct.ap.test.conversion.java8time.localdatetoxmlgregoriancalendarconversion.SourceTargetMapper; import org.mapstruct.ap.test.conversion.java8time.localdatetoxmlgregoriancalendarconversion.Target; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian */ @IssueKey("580") @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class LocalDateToXMLGregorianCalendarConversionTest { - @Test + @ProcessorTest public void shouldNullCheckOnBuiltinAndConversion() { Target target = SourceTargetMapper.INSTANCE.toTarget( new Source() ); @@ -56,7 +39,7 @@ public void shouldNullCheckOnBuiltinAndConversion() { assertThat( source.getDate() ).isNull(); } - @Test + @ProcessorTest public void shouldMapCorrectlyOnBuiltinAndConversion() throws Exception { XMLGregorianCalendar calendarDate = DatatypeFactory.newInstance().newXMLGregorianCalendarDate( 2007, diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/OptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/OptionalSource.java new file mode 100644 index 0000000000..cf94f31869 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/OptionalSource.java @@ -0,0 +1,160 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time; + +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.Period; +import java.time.ZonedDateTime; +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class OptionalSource { + + private Optional zonedDateTime = Optional.empty(); + + private Optional localDateTime = Optional.empty(); + + private Optional localDate = Optional.empty(); + + private Optional localTime = Optional.empty(); + + private Optional forCalendarConversion = Optional.empty(); + + private Optional forDateConversionWithZonedDateTime = Optional.empty(); + + private Optional forDateConversionWithLocalDateTime = Optional.empty(); + + private Optional forDateConversionWithLocalDate = Optional.empty(); + + private Optional forSqlDateConversionWithLocalDate = Optional.empty(); + + private Optional forDateConversionWithInstant = Optional.empty(); + + private Optional forLocalDateTimeConversionWithLocalDate = Optional.empty(); + + private Optional forInstantConversionWithString = Optional.empty(); + + private Optional forPeriodConversionWithString = Optional.empty(); + + private Optional forDurationConversionWithString = Optional.empty(); + + public Optional getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(Optional dateTime) { + this.zonedDateTime = dateTime; + } + + public Optional getLocalDateTime() { + return localDateTime; + } + + public void setLocalDateTime(Optional localDateTime) { + this.localDateTime = localDateTime; + } + + public Optional getLocalDate() { + return localDate; + } + + public void setLocalDate(Optional localDate) { + this.localDate = localDate; + } + + public Optional getLocalTime() { + return localTime; + } + + public void setLocalTime(Optional localTime) { + this.localTime = localTime; + } + + public Optional getForCalendarConversion() { + return forCalendarConversion; + } + + public void setForCalendarConversion(Optional forCalendarConversion) { + this.forCalendarConversion = forCalendarConversion; + } + + public Optional getForDateConversionWithZonedDateTime() { + return forDateConversionWithZonedDateTime; + } + + public void setForDateConversionWithZonedDateTime(Optional forDateConversionWithZonedDateTime) { + this.forDateConversionWithZonedDateTime = forDateConversionWithZonedDateTime; + } + + public Optional getForDateConversionWithLocalDateTime() { + return forDateConversionWithLocalDateTime; + } + + public void setForDateConversionWithLocalDateTime(Optional forDateConversionWithLocalDateTime) { + this.forDateConversionWithLocalDateTime = forDateConversionWithLocalDateTime; + } + + public Optional getForDateConversionWithLocalDate() { + return forDateConversionWithLocalDate; + } + + public void setForDateConversionWithLocalDate(Optional forDateConversionWithLocalDate) { + this.forDateConversionWithLocalDate = forDateConversionWithLocalDate; + } + + public Optional getForSqlDateConversionWithLocalDate() { + return forSqlDateConversionWithLocalDate; + } + + public void setForSqlDateConversionWithLocalDate(Optional forSqlDateConversionWithLocalDate) { + this.forSqlDateConversionWithLocalDate = forSqlDateConversionWithLocalDate; + } + + public Optional getForDateConversionWithInstant() { + return forDateConversionWithInstant; + } + + public void setForDateConversionWithInstant(Optional forDateConversionWithInstant) { + this.forDateConversionWithInstant = forDateConversionWithInstant; + } + + public Optional getForLocalDateTimeConversionWithLocalDate() { + return forLocalDateTimeConversionWithLocalDate; + } + + public void setForLocalDateTimeConversionWithLocalDate( + Optional forLocalDateTimeConversionWithLocalDate) { + this.forLocalDateTimeConversionWithLocalDate = forLocalDateTimeConversionWithLocalDate; + } + + public Optional getForInstantConversionWithString() { + return forInstantConversionWithString; + } + + public void setForInstantConversionWithString(Optional forInstantConversionWithString) { + this.forInstantConversionWithString = forInstantConversionWithString; + } + + public Optional getForPeriodConversionWithString() { + return forPeriodConversionWithString; + } + + public void setForPeriodConversionWithString(Optional forPeriodConversionWithString) { + this.forPeriodConversionWithString = forPeriodConversionWithString; + } + + public Optional getForDurationConversionWithString() { + return forDurationConversionWithString; + } + + public void setForDurationConversionWithString(Optional forDurationConversionWithString) { + this.forDurationConversionWithString = forDurationConversionWithString; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/OptionalSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/OptionalSourceTargetMapper.java new file mode 100644 index 0000000000..a266309b61 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/OptionalSourceTargetMapper.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface OptionalSourceTargetMapper { + + String DATE_TIME_FORMAT = "dd.MM.yyyy HH:mm z"; + + String LOCAL_DATE_TIME_FORMAT = "dd.MM.yyyy HH:mm"; + + String LOCAL_DATE_FORMAT = "dd.MM.yyyy"; + + String LOCAL_TIME_FORMAT = "HH:mm"; + + OptionalSourceTargetMapper INSTANCE = Mappers.getMapper( OptionalSourceTargetMapper.class ); + + @Mapping(target = "zonedDateTime", dateFormat = DATE_TIME_FORMAT) + @Mapping(target = "localDateTime", dateFormat = LOCAL_DATE_TIME_FORMAT) + @Mapping(target = "localDate", dateFormat = LOCAL_DATE_FORMAT) + @Mapping(target = "localTime", dateFormat = LOCAL_TIME_FORMAT) + Target sourceToTarget(OptionalSource source); + + @Mapping(target = "zonedDateTime", dateFormat = DATE_TIME_FORMAT) + @Mapping(target = "localDateTime", dateFormat = LOCAL_DATE_TIME_FORMAT) + @Mapping(target = "localDate", dateFormat = LOCAL_DATE_FORMAT) + @Mapping(target = "localTime", dateFormat = LOCAL_TIME_FORMAT) + Target sourceToTargetDefaultMapping(OptionalSource source); + + @Mapping(target = "zonedDateTime", dateFormat = DATE_TIME_FORMAT) + Target sourceToTargetDateTimeMapped(OptionalSource source); + + @Mapping(target = "localDateTime", dateFormat = LOCAL_DATE_TIME_FORMAT) + Target sourceToTargetLocalDateTimeMapped(OptionalSource source); + + @Mapping(target = "localDate", dateFormat = LOCAL_DATE_FORMAT) + Target sourceToTargetLocalDateMapped(OptionalSource source); + + @Mapping(target = "localTime", dateFormat = LOCAL_TIME_FORMAT) + Target sourceToTargetLocalTimeMapped(OptionalSource source); + + @Mapping(target = "zonedDateTime", dateFormat = DATE_TIME_FORMAT) + @Mapping(target = "localDateTime", dateFormat = LOCAL_DATE_TIME_FORMAT) + @Mapping(target = "localDate", dateFormat = LOCAL_DATE_FORMAT) + @Mapping(target = "localTime", dateFormat = LOCAL_TIME_FORMAT) + OptionalSource targetToSource(Target target); + + @Mapping(target = "zonedDateTime", dateFormat = DATE_TIME_FORMAT) + OptionalSource targetToSourceDateTimeMapped(Target target); + + @Mapping(target = "localDateTime", dateFormat = LOCAL_DATE_TIME_FORMAT) + OptionalSource targetToSourceLocalDateTimeMapped(Target target); + + @Mapping(target = "localDate", dateFormat = LOCAL_DATE_FORMAT) + OptionalSource targetToSourceLocalDateMapped(Target target); + + @Mapping(target = "localTime", dateFormat = LOCAL_TIME_FORMAT) + OptionalSource targetToSourceLocalTimeMapped(Target target); + + @InheritInverseConfiguration(name = "sourceToTarget") + OptionalSource targetToSourceDefaultMapping(Target target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Source.java index e2ea78bde0..93479f8a86 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Source.java @@ -1,26 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time; +import java.time.Duration; +import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Period; import java.time.ZonedDateTime; /** @@ -44,6 +34,18 @@ public class Source { private LocalDate forDateConversionWithLocalDate; + private LocalDate forSqlDateConversionWithLocalDate; + + private Instant forDateConversionWithInstant; + + private LocalDate forLocalDateTimeConversionWithLocalDate; + + private Instant forInstantConversionWithString; + + private Period forPeriodConversionWithString; + + private Duration forDurationConversionWithString; + public ZonedDateTime getZonedDateTime() { return zonedDateTime; } @@ -107,4 +109,52 @@ public LocalDate getForDateConversionWithLocalDate() { public void setForDateConversionWithLocalDate(LocalDate forDateConversionWithLocalDate) { this.forDateConversionWithLocalDate = forDateConversionWithLocalDate; } + + public LocalDate getForSqlDateConversionWithLocalDate() { + return forSqlDateConversionWithLocalDate; + } + + public void setForSqlDateConversionWithLocalDate(LocalDate forSqlDateConversionWithLocalDate) { + this.forSqlDateConversionWithLocalDate = forSqlDateConversionWithLocalDate; + } + + public Instant getForDateConversionWithInstant() { + return forDateConversionWithInstant; + } + + public void setForDateConversionWithInstant(Instant forDateConversionWithInstant) { + this.forDateConversionWithInstant = forDateConversionWithInstant; + } + + public LocalDate getForLocalDateTimeConversionWithLocalDate() { + return forLocalDateTimeConversionWithLocalDate; + } + + public void setForLocalDateTimeConversionWithLocalDate(LocalDate forLocalDateTimeConversionWithLocalDate) { + this.forLocalDateTimeConversionWithLocalDate = forLocalDateTimeConversionWithLocalDate; + } + + public Instant getForInstantConversionWithString() { + return forInstantConversionWithString; + } + + public void setForInstantConversionWithString(Instant forInstantConversionWithString) { + this.forInstantConversionWithString = forInstantConversionWithString; + } + + public Period getForPeriodConversionWithString() { + return forPeriodConversionWithString; + } + + public void setForPeriodConversionWithString(Period forPeriodConversionWithString) { + this.forPeriodConversionWithString = forPeriodConversionWithString; + } + + public Duration getForDurationConversionWithString() { + return forDurationConversionWithString; + } + + public void setForDurationConversionWithString(Duration forDurationConversionWithString) { + this.forDurationConversionWithString = forDurationConversionWithString; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapper.java index e8ff00c4d3..f2351f4175 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time; @@ -39,6 +26,7 @@ public interface SourceTargetMapper { String LOCAL_TIME_FORMAT = "HH:mm"; SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + @Mappings( { @Mapping( target = "zonedDateTime", dateFormat = DATE_TIME_FORMAT ), @Mapping( target = "localDateTime", dateFormat = LOCAL_DATE_TIME_FORMAT ), @Mapping( target = "localDate", dateFormat = LOCAL_DATE_FORMAT ), diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Target.java index 68c8430b82..d2a4878731 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/Target.java @@ -1,23 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time; +import java.time.LocalDateTime; import java.util.Calendar; import java.util.Date; @@ -42,6 +30,18 @@ public class Target { private Date forDateConversionWithLocalDate; + private java.sql.Date forSqlDateConversionWithLocalDate; + + private Date forDateConversionWithInstant; + + private LocalDateTime forLocalDateTimeConversionWithLocalDate; + + private String forInstantConversionWithString; + + private String forPeriodConversionWithString; + + private String forDurationConversionWithString; + public String getZonedDateTime() { return zonedDateTime; } @@ -105,4 +105,52 @@ public Date getForDateConversionWithLocalDate() { public void setForDateConversionWithLocalDate(Date forDateConversionWithLocalDate) { this.forDateConversionWithLocalDate = forDateConversionWithLocalDate; } + + public java.sql.Date getForSqlDateConversionWithLocalDate() { + return forSqlDateConversionWithLocalDate; + } + + public void setForSqlDateConversionWithLocalDate(java.sql.Date forSqlDateConversionWithLocalDate) { + this.forSqlDateConversionWithLocalDate = forSqlDateConversionWithLocalDate; + } + + public Date getForDateConversionWithInstant() { + return forDateConversionWithInstant; + } + + public void setForDateConversionWithInstant(Date forDateConversionWithInstant) { + this.forDateConversionWithInstant = forDateConversionWithInstant; + } + + public LocalDateTime getForLocalDateTimeConversionWithLocalDate() { + return forLocalDateTimeConversionWithLocalDate; + } + + public void setForLocalDateTimeConversionWithLocalDate(LocalDateTime forLocalDateTimeConversionWithLocalDate) { + this.forLocalDateTimeConversionWithLocalDate = forLocalDateTimeConversionWithLocalDate; + } + + public String getForInstantConversionWithString() { + return forInstantConversionWithString; + } + + public void setForInstantConversionWithString(String forInstantConversionWithString) { + this.forInstantConversionWithString = forInstantConversionWithString; + } + + public String getForPeriodConversionWithString() { + return forPeriodConversionWithString; + } + + public void setForPeriodConversionWithString(String forPeriodConversionWithString) { + this.forPeriodConversionWithString = forPeriodConversionWithString; + } + + public String getForDurationConversionWithString() { + return forDurationConversionWithString; + } + + public void setForDurationConversionWithString(String forDurationConversionWithString) { + this.forDurationConversionWithString = forDurationConversionWithString; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/ZonedOffsetDateTimeToLocalDateTimeConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/ZonedOffsetDateTimeToLocalDateTimeConversionTest.java new file mode 100644 index 0000000000..ab17980e96 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/ZonedOffsetDateTimeToLocalDateTimeConversionTest.java @@ -0,0 +1,113 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time; + +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.conversion.java8time.zonedoffsetdatetimetolocaldatetimeconversion.Source; +import org.mapstruct.ap.test.conversion.java8time.zonedoffsetdatetimetolocaldatetimeconversion.SourceTargetMapper; +import org.mapstruct.ap.test.conversion.java8time.zonedoffsetdatetimetolocaldatetimeconversion.Target; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) +@IssueKey("4027") +public class ZonedOffsetDateTimeToLocalDateTimeConversionTest { + + @RegisterExtension + GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( SourceTargetMapper.class ); + + @ProcessorTest + public void testZonedDateTimeToLocalDateTimeMapping() { + ZonedDateTime zonedDateTime = ZonedDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneId.of( "UTC" ) ); + Source source = new Source(); + source.setZonedDateTime( zonedDateTime ); + Target target = SourceTargetMapper.INSTANCE.toTarget( source ); + assertThat( target.getZonedDateTime() ) + .isEqualTo( LocalDateTime.of( 2024, 1, 1, 12, 30, 0 ) ); + } + + @ProcessorTest + public void testOffsetDateTimeToLocalDateTimeMapping() { + OffsetDateTime offsetDateTime = OffsetDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ); + Source source = new Source(); + source.setOffsetDateTime( offsetDateTime ); + Target target = SourceTargetMapper.INSTANCE.toTarget( source ); + assertThat( target.getOffsetDateTime() ) + .isEqualTo( LocalDateTime.of( 2024, 1, 1, 12, 30, 0 ) ); + } + + @ProcessorTest + public void testLocalDateTimeToZonedDateTimeMapping() { + LocalDateTime localDateTime = LocalDateTime.of( 2024, 1, 1, 12, 30, 0 ); + Target target = new Target(); + target.setZonedDateTime( localDateTime ); + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + assertThat( source.getZonedDateTime() ) + .isEqualTo( ZonedDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ) ); + } + + @ProcessorTest + public void testLocalDateTimeToOffsetDateTimeMapping() { + LocalDateTime localDateTime = LocalDateTime.of( 2024, 1, 1, 12, 30, 0 ); + Target target = new Target(); + target.setOffsetDateTime( localDateTime ); + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + assertThat( source.getOffsetDateTime() ) + .isEqualTo( OffsetDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ) ); + } + + @ProcessorTest + public void testZonedDateTimeToInstantMapping() { + ZonedDateTime zonedDateTime = ZonedDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ); + Source source = new Source(); + source.setZonedDateTimeAsInstant( zonedDateTime ); + Target target = SourceTargetMapper.INSTANCE.toTarget( source ); + assertThat( target.getZonedDateTimeAsInstant() ) + .isEqualTo( Instant.parse( "2024-01-01T12:30:00Z" ) ); + } + + @ProcessorTest + public void testOffsetDateTimeToInstantMapping() { + OffsetDateTime offsetDateTime = OffsetDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ); + Source source = new Source(); + source.setOffsetDateTimeAsInstant( offsetDateTime ); + Target target = SourceTargetMapper.INSTANCE.toTarget( source ); + assertThat( target.getOffsetDateTimeAsInstant() ) + .isEqualTo( Instant.parse( "2024-01-01T12:30:00Z" ) ); + } + + @ProcessorTest + public void testInstantToZonedDateTimeMapping() { + Instant instant = Instant.parse( "2024-01-01T12:30:00Z" ); + Target target = new Target(); + target.setZonedDateTimeAsInstant( instant ); + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + assertThat( source.getZonedDateTimeAsInstant() ) + .isEqualTo( ZonedDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ) ); + } + + @ProcessorTest + public void testInstantToOffsetDateTimeMapping() { + Instant instant = Instant.parse( "2024-01-01T12:30:00Z" ); + Target target = new Target(); + target.setOffsetDateTimeAsInstant( instant ); + Source source = SourceTargetMapper.INSTANCE.toSource( target ); + assertThat( source.getOffsetDateTimeAsInstant() ) + .isEqualTo( OffsetDateTime.of( 2024, 1, 1, 12, 30, 0, 0, ZoneOffset.UTC ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Source.java new file mode 100644 index 0000000000..f83721cbb5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Source.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.custompatterndatetimeformattergenerated; + +import java.time.LocalDateTime; + +public class Source { + + private LocalDateTime localDateTime1; + private LocalDateTime localDateTime2; + private LocalDateTime localDateTime3; + + public LocalDateTime getLocalDateTime1() { + return localDateTime1; + } + + public void setLocalDateTime1(LocalDateTime localDateTime1) { + this.localDateTime1 = localDateTime1; + } + + public LocalDateTime getLocalDateTime2() { + return localDateTime2; + } + + public void setLocalDateTime2(LocalDateTime localDateTime2) { + this.localDateTime2 = localDateTime2; + } + + public LocalDateTime getLocalDateTime3() { + return localDateTime3; + } + + public void setLocalDateTime3(LocalDateTime localDateTime3) { + this.localDateTime3 = localDateTime3; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapper.java new file mode 100644 index 0000000000..960ceec3b9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/SourceTargetMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.custompatterndatetimeformattergenerated; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SourceTargetMapper { + + String LOCAL_DATE_TIME_FORMAT = "dd.MM.yyyy HH:mm"; + String VERY_SIMILAR_LOCAL_DATE_TIME_FORMAT = "dd.MM.yyyy HH.mm"; + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping(target = "localDateTime1", dateFormat = LOCAL_DATE_TIME_FORMAT) + @Mapping(target = "localDateTime2", dateFormat = LOCAL_DATE_TIME_FORMAT) + @Mapping(target = "localDateTime3", dateFormat = VERY_SIMILAR_LOCAL_DATE_TIME_FORMAT) + Target map(Source source); + + @InheritInverseConfiguration + Source map(Target target); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Target.java new file mode 100644 index 0000000000..7d265ba4aa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/custompatterndatetimeformattergenerated/Target.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.custompatterndatetimeformattergenerated; + +public class Target { + + private String localDateTime1; + private String localDateTime2; + private String localDateTime3; + + public String getLocalDateTime1() { + return localDateTime1; + } + + public void setLocalDateTime1(String localDateTime1) { + this.localDateTime1 = localDateTime1; + } + + public String getLocalDateTime2() { + return localDateTime2; + } + + public void setLocalDateTime2(String localDateTime2) { + this.localDateTime2 = localDateTime2; + } + + public String getLocalDateTime3() { + return localDateTime3; + } + + public void setLocalDateTime3(String localDateTime3) { + this.localDateTime3 = localDateTime3; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/Source.java new file mode 100644 index 0000000000..d79ad6072d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/Source.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.localdatetimetoxmlgregoriancalendarconversion; + +import javax.xml.datatype.XMLGregorianCalendar; + +/** + * @author Andrei Arlou + */ +public class Source { + private XMLGregorianCalendar xmlGregorianCalendar; + + public XMLGregorianCalendar getXmlGregorianCalendar() { + return xmlGregorianCalendar; + } + + public void setXmlGregorianCalendar(XMLGregorianCalendar xmlGregorianCalendar) { + this.xmlGregorianCalendar = xmlGregorianCalendar; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/SourceTargetMapper.java new file mode 100644 index 0000000000..ed4c1d374d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/SourceTargetMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.localdatetimetoxmlgregoriancalendarconversion; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Andrei Arlou + */ +@Mapper +public interface SourceTargetMapper { + + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + @Mapping(target = "localDateTime", source = "xmlGregorianCalendar") + Target toTarget(Source source); + + @Mapping(target = "xmlGregorianCalendar", source = "localDateTime") + Source toSource(Target target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/Target.java new file mode 100644 index 0000000000..b8fc51e6d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetimetoxmlgregoriancalendarconversion/Target.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.localdatetimetoxmlgregoriancalendarconversion; + +import java.time.LocalDateTime; + +/** + * @author Andrei Arlou + */ +public class Target { + private LocalDateTime localDateTime; + + public LocalDateTime getLocalDateTime() { + return localDateTime; + } + + public void setLocalDateTime(LocalDateTime localDateTime) { + this.localDateTime = localDateTime; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Source.java index 151888a225..081fc1edb9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Source.java @@ -1,26 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time.localdatetoxmlgregoriancalendarconversion; import javax.xml.datatype.XMLGregorianCalendar; - /** * @author Andreas Gudian */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/SourceTargetMapper.java index 3e9046b739..5c8598241a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time.localdatetoxmlgregoriancalendarconversion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Target.java index 5e35b98e43..6b9fd2bc78 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/localdatetoxmlgregoriancalendarconversion/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.java8time.localdatetoxmlgregoriancalendarconversion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/Source.java new file mode 100644 index 0000000000..18bd99825c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/Source.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.zonedoffsetdatetimetolocaldatetimeconversion; + +import java.time.OffsetDateTime; +import java.time.ZonedDateTime; + +public class Source { + private ZonedDateTime zonedDateTime; + private OffsetDateTime offsetDateTime; + private ZonedDateTime zonedDateTimeAsInstant; + private OffsetDateTime offsetDateTimeAsInstant; + + public ZonedDateTime getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(ZonedDateTime zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } + + public OffsetDateTime getOffsetDateTime() { + return offsetDateTime; + } + + public void setOffsetDateTime(OffsetDateTime offsetDateTime) { + this.offsetDateTime = offsetDateTime; + } + + public ZonedDateTime getZonedDateTimeAsInstant() { + return zonedDateTimeAsInstant; + } + + public void setZonedDateTimeAsInstant(ZonedDateTime zonedDateTimeAsInstant) { + this.zonedDateTimeAsInstant = zonedDateTimeAsInstant; + } + + public OffsetDateTime getOffsetDateTimeAsInstant() { + return offsetDateTimeAsInstant; + } + + public void setOffsetDateTimeAsInstant(OffsetDateTime offsetDateTimeAsInstant) { + this.offsetDateTimeAsInstant = offsetDateTimeAsInstant; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/SourceTargetMapper.java new file mode 100644 index 0000000000..43bee5f77f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/SourceTargetMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.zonedoffsetdatetimetolocaldatetimeconversion; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SourceTargetMapper { + SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); + + Target toTarget(Source source); + + Source toSource(Target target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/Target.java new file mode 100644 index 0000000000..b43b9f6843 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/java8time/zonedoffsetdatetimetolocaldatetimeconversion/Target.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.java8time.zonedoffsetdatetimetolocaldatetimeconversion; + +import java.time.Instant; +import java.time.LocalDateTime; + +public class Target { + private LocalDateTime zonedDateTime; + private LocalDateTime offsetDateTime; + private Instant zonedDateTimeAsInstant; + private Instant offsetDateTimeAsInstant; + + public LocalDateTime getOffsetDateTime() { + return offsetDateTime; + } + + public void setOffsetDateTime(LocalDateTime offsetDateTime) { + this.offsetDateTime = offsetDateTime; + } + + public LocalDateTime getZonedDateTime() { + return zonedDateTime; + } + + public void setZonedDateTime(LocalDateTime zonedDateTime) { + this.zonedDateTime = zonedDateTime; + } + + public Instant getZonedDateTimeAsInstant() { + return zonedDateTimeAsInstant; + } + + public void setZonedDateTimeAsInstant(Instant zonedDateTimeAsInstant) { + this.zonedDateTimeAsInstant = zonedDateTimeAsInstant; + } + + public Instant getOffsetDateTimeAsInstant() { + return offsetDateTimeAsInstant; + } + + public void setOffsetDateTimeAsInstant(Instant offsetDateTimeAsInstant) { + this.offsetDateTimeAsInstant = offsetDateTimeAsInstant; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/JodaConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/JodaConversionTest.java index 1d9ab3cea0..d447c455ff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/JodaConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/JodaConversionTest.java @@ -1,27 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Calendar; -import java.util.Locale; import java.util.TimeZone; import org.joda.time.DateTime; @@ -29,29 +13,26 @@ import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import org.joda.time.LocalTime; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.DefaultLocale; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJoda; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests the conversion between Joda-Time types and String/Date/Calendar. * * @author Timo Eckhardt */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) @IssueKey("75") +@DefaultLocale("de") +@WithJoda public class JodaConversionTest { - @Before - public void setDefaultLocale() { - Locale.setDefault( Locale.GERMAN ); - } - - @Test + @ProcessorTest public void testDateTimeToString() { Source src = new Source(); src.setDateTime( new DateTime( 2014, 1, 1, 0, 0, 0, DateTimeZone.UTC ) ); @@ -60,7 +41,7 @@ public void testDateTimeToString() { assertThat( target.getDateTime() ).isEqualTo( "01.01.2014 00:00 UTC" ); } - @Test + @ProcessorTest public void testLocalDateTimeToString() { Source src = new Source(); src.setLocalDateTime( new LocalDateTime( 2014, 1, 1, 0, 0 ) ); @@ -69,7 +50,7 @@ public void testLocalDateTimeToString() { assertThat( target.getLocalDateTime() ).isEqualTo( "01.01.2014 00:00" ); } - @Test + @ProcessorTest public void testLocalDateToString() { Source src = new Source(); src.setLocalDate( new LocalDate( 2014, 1, 1 ) ); @@ -78,7 +59,7 @@ public void testLocalDateToString() { assertThat( target.getLocalDate() ).isEqualTo( "01.01.2014" ); } - @Test + @ProcessorTest public void testLocalTimeToString() { Source src = new Source(); src.setLocalTime( new LocalTime( 0, 0 ) ); @@ -87,7 +68,7 @@ public void testLocalTimeToString() { assertThat( target.getLocalTime() ).isEqualTo( "00:00" ); } - @Test + @ProcessorTest public void testSourceToTargetMappingForStrings() { Source src = new Source(); src.setLocalTime( new LocalTime( 0, 0 ) ); @@ -107,13 +88,13 @@ public void testSourceToTargetMappingForStrings() { // and now with default mappings target = SourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( src ); assertThat( target ).isNotNull(); - assertThat( target.getDateTime() ).isEqualTo( "1. Januar 2014 00:00:00 UTC" ); - assertThat( target.getLocalDateTime() ).isEqualTo( "1. Januar 2014 00:00:00" ); + assertThat( target.getDateTime() ).isEqualTo( "1. Januar 2014, 00:00:00 UTC" ); + assertThat( target.getLocalDateTime() ).isEqualTo( "1. Januar 2014, 00:00:00" ); assertThat( target.getLocalDate() ).isEqualTo( "1. Januar 2014" ); assertThat( target.getLocalTime() ).isEqualTo( "00:00:00" ); } - @Test + @ProcessorTest public void testStringToDateTime() { String dateTimeAsString = "01.01.2014 00:00 UTC"; Target target = new Target(); @@ -126,7 +107,7 @@ public void testStringToDateTime() { assertThat( src.getDateTime() ).isEqualTo( sourceDateTime ); } - @Test + @ProcessorTest public void testStringToLocalDateTime() { String dateTimeAsString = "01.01.2014 00:00"; Target target = new Target(); @@ -139,7 +120,7 @@ public void testStringToLocalDateTime() { assertThat( src.getLocalDateTime() ).isEqualTo( sourceDateTime ); } - @Test + @ProcessorTest public void testStringToLocalDate() { String dateTimeAsString = "01.01.2014"; Target target = new Target(); @@ -152,7 +133,7 @@ public void testStringToLocalDate() { assertThat( src.getLocalDate() ).isEqualTo( sourceDate ); } - @Test + @ProcessorTest public void testStringToLocalTime() { String dateTimeAsString = "00:00"; Target target = new Target(); @@ -165,7 +146,7 @@ public void testStringToLocalTime() { assertThat( src.getLocalTime() ).isEqualTo( sourceTime ); } - @Test + @ProcessorTest public void testTargetToSourceNullMapping() { Target target = new Target(); Source src = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -177,7 +158,7 @@ public void testTargetToSourceNullMapping() { assertThat( src.getLocalTime() ).isNull(); } - @Test + @ProcessorTest public void testTargetToSourceMappingForStrings() { Target target = new Target(); @@ -194,7 +175,7 @@ public void testTargetToSourceMappingForStrings() { assertThat( src.getLocalTime() ).isEqualTo( new LocalTime( 0, 0 ) ); } - @Test + @ProcessorTest public void testCalendar() { Calendar calendar = Calendar.getInstance( TimeZone.getTimeZone( "CET" ) ); DateTime dateTimeWithCalendar = new DateTime( calendar ); @@ -210,7 +191,7 @@ public void testCalendar() { assertThat( mappedSource.getDateTimeForCalendarConversion() ).isEqualTo( dateTimeWithCalendar ); } - @Test + @ProcessorTest @WithClasses({ StringToLocalDateMapper.class, SourceWithStringDate.class, TargetWithLocalDate.class }) @IssueKey("456") public void testStringToLocalDateUsingDefaultFormat() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Source.java index 1a2ababef7..5c23318479 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceTargetMapper.java index ff6546ad3d..d1c2723c5c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceWithStringDate.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceWithStringDate.java index 46ef4e1413..ba209d3db4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceWithStringDate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/SourceWithStringDate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/StringToLocalDateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/StringToLocalDateMapper.java index 7e55dfb045..52dfd76aca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/StringToLocalDateMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/StringToLocalDateMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Target.java index a654f48baf..ef12f646cf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/TargetWithLocalDate.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/TargetWithLocalDate.java index 8efa3c9ff7..93c4607cab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/TargetWithLocalDate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/jodatime/TargetWithLocalDate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.jodatime; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleConversionTest.java new file mode 100644 index 0000000000..cba7785512 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleConversionTest.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.locale; + +import java.util.Locale; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests conversions between {@link Locale} and String. + * + * @author Jason Bodnar + */ +@IssueKey("3172") +@WithClasses({ LocaleSource.class, LocaleTarget.class, LocaleMapper.class }) +public class LocaleConversionTest { + + @ProcessorTest + public void shouldApplyLocaleConversion() { + LocaleSource source = new LocaleSource(); + source.setLocaleA( Locale.getDefault() ); + + LocaleTarget target = LocaleMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getLocaleA() ).isEqualTo( source.getLocaleA().toLanguageTag() ); + } + + @ProcessorTest + public void shouldApplyReverseLocaleConversion() { + LocaleTarget target = new LocaleTarget(); + target.setLocaleA( Locale.getDefault().toLanguageTag() ); + + LocaleSource source = LocaleMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getLocaleA() ).isEqualTo( Locale.forLanguageTag( target.getLocaleA() ) ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleMapper.java new file mode 100644 index 0000000000..3da3fc4ae4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.locale; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface LocaleMapper { + + LocaleMapper INSTANCE = Mappers.getMapper( LocaleMapper.class ); + + LocaleTarget sourceToTarget(LocaleSource source); + + LocaleSource targetToSource(LocaleTarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleSource.java new file mode 100644 index 0000000000..69ea5bda2d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleSource.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.locale; + +import java.util.Locale; + +/** + * @author Jason Bodnar + */ +public class LocaleSource { + private Locale localeA; + + public Locale getLocaleA() { + return localeA; + } + + public void setLocaleA(Locale localeA) { + this.localeA = localeA; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleTarget.java new file mode 100644 index 0000000000..000ff86b05 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/locale/LocaleTarget.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.locale; + +/** + * @author Jason Bodnar + */ +public class LocaleTarget { + private String localeA; + + public String getLocaleA() { + return localeA; + } + + public void setLocaleA(String localeA) { + this.localeA = localeA; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryDto.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryDto.java new file mode 100644 index 0000000000..3bc144511e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryDto.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +public class CutleryInventoryDto { + + private short numberOfKnifes; + private int numberOfForks; + private byte numberOfSpoons; + private int drawerId; + + private float approximateKnifeLength; + + public short getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(short numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public int getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(int numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public byte getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(byte numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public float getApproximateKnifeLength() { + return approximateKnifeLength; + } + + public void setApproximateKnifeLength(float approximateKnifeLength) { + this.approximateKnifeLength = approximateKnifeLength; + } + + public int getDrawerId() { + return drawerId; + } + + public void setDrawerId(int drawerId) { + this.drawerId = drawerId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryEntity.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryEntity.java new file mode 100644 index 0000000000..755dbc3637 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryEntity.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +public class CutleryInventoryEntity { + + private int numberOfKnifes; + private Long numberOfForks; + private short numberOfSpoons; + private String drawerId; + + private double approximateKnifeLength; + + public int getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(int numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public Long getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(Long numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public short getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(short numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public double getApproximateKnifeLength() { + return approximateKnifeLength; + } + + public void setApproximateKnifeLength(double approximateKnifeLength) { + this.approximateKnifeLength = approximateKnifeLength; + } + + public String getDrawerId() { + return drawerId; + } + + public void setDrawerId(String drawerId) { + this.drawerId = drawerId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryMapper.java new file mode 100644 index 0000000000..258f696d5b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/CutleryInventoryMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface CutleryInventoryMapper { + + CutleryInventoryMapper INSTANCE = Mappers.getMapper( CutleryInventoryMapper.class ); + + CutleryInventoryEntity map( CutleryInventoryDto in ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper1.java new file mode 100644 index 0000000000..b96745c3cc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper1.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerMapper1 { + + ErroneousKitchenDrawerMapper1 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerMapper1.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "numberOfForks", source = "numberOfForks" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper3.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper3.java new file mode 100644 index 0000000000..1b270dc395 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper3.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR, uses = VerySpecialNumberMapper.class ) +public interface ErroneousKitchenDrawerMapper3 { + + ErroneousKitchenDrawerMapper3 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerMapper3.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "numberOfSpoons", source = "numberOfSpoons" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper4.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper4.java new file mode 100644 index 0000000000..fc02081182 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper4.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerMapper4 { + + ErroneousKitchenDrawerMapper4 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerMapper4.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "depth", source = "depth" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper5.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper5.java new file mode 100644 index 0000000000..ef86586060 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper5.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerMapper5 { + + ErroneousKitchenDrawerMapper5 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerMapper5.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "length", source = "length" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper6.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper6.java new file mode 100644 index 0000000000..c33f1bd662 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerMapper6.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerMapper6 { + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "drawerId", source = "drawerId" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper1.java new file mode 100644 index 0000000000..d83b368bce --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper1.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerOptionalMapper1 { + + ErroneousKitchenDrawerOptionalMapper1 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerOptionalMapper1.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "numberOfForks", source = "numberOfForks" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper3.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper3.java new file mode 100644 index 0000000000..7d1824a5b1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper3.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR, uses = VerySpecialNumberMapper.class ) +public interface ErroneousKitchenDrawerOptionalMapper3 { + + ErroneousKitchenDrawerOptionalMapper3 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerOptionalMapper3.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "numberOfSpoons", source = "numberOfSpoons" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper4.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper4.java new file mode 100644 index 0000000000..edd33c71d9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper4.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerOptionalMapper4 { + + ErroneousKitchenDrawerOptionalMapper4 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerOptionalMapper4.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "depth", source = "depth" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper5.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper5.java new file mode 100644 index 0000000000..bad921a7c2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper5.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerOptionalMapper5 { + + ErroneousKitchenDrawerOptionalMapper5 INSTANCE = Mappers.getMapper( ErroneousKitchenDrawerOptionalMapper5.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "length", source = "length" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper6.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper6.java new file mode 100644 index 0000000000..acd2e0876f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ErroneousKitchenDrawerOptionalMapper6.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +@Mapper( typeConversionPolicy = ReportingPolicy.ERROR ) +public interface ErroneousKitchenDrawerOptionalMapper6 { + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "drawerId", source = "drawerId" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerMapper2.java new file mode 100644 index 0000000000..2ececec67b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerMapper2.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.WARN ) +public interface KitchenDrawerMapper2 { + + KitchenDrawerMapper2 INSTANCE = Mappers.getMapper( KitchenDrawerMapper2.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "numberOfKnifes", source = "numberOfKnifes" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerMapper6.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerMapper6.java new file mode 100644 index 0000000000..8932858109 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerMapper6.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.WARN, uses = VerySpecialNumberMapper.class ) +public interface KitchenDrawerMapper6 { + + KitchenDrawerMapper6 INSTANCE = Mappers.getMapper( KitchenDrawerMapper6.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "height", source = "height" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerOptionalMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerOptionalMapper2.java new file mode 100644 index 0000000000..92862d3320 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerOptionalMapper2.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.WARN ) +public interface KitchenDrawerOptionalMapper2 { + + KitchenDrawerOptionalMapper2 INSTANCE = Mappers.getMapper( KitchenDrawerOptionalMapper2.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "numberOfKnifes", source = "numberOfKnifes" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerOptionalMapper6.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerOptionalMapper6.java new file mode 100644 index 0000000000..2b3e982584 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/KitchenDrawerOptionalMapper6.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( typeConversionPolicy = ReportingPolicy.WARN, uses = VerySpecialNumberMapper.class ) +public interface KitchenDrawerOptionalMapper6 { + + KitchenDrawerOptionalMapper6 INSTANCE = Mappers.getMapper( KitchenDrawerOptionalMapper6.class ); + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "height", source = "height" ) + RegularKitchenDrawerEntity map( OversizedKitchenDrawerOptionalDto dto ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ListMapper.java new file mode 100644 index 0000000000..b253a26f1d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/ListMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.WARN ) +public interface ListMapper { + + List map(List in); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/LossyConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/LossyConversionTest.java new file mode 100644 index 0000000000..3468da4535 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/LossyConversionTest.java @@ -0,0 +1,264 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.withinPercentage; + +/** + * Tests the conversion between Joda-Time types and String/Date/Calendar. + * + * @author Sjaak Derksen + */ +@WithClasses({ + OversizedKitchenDrawerDto.class, + OversizedKitchenDrawerOptionalDto.class, + RegularKitchenDrawerEntity.class, + VerySpecialNumber.class, + VerySpecialNumberMapper.class, + CutleryInventoryMapper.class, + CutleryInventoryDto.class, + CutleryInventoryEntity.class +}) +@IssueKey("5") +public class LossyConversionTest { + + @ProcessorTest + public void testNoErrorCase() { + + CutleryInventoryDto dto = new CutleryInventoryDto(); + dto.setNumberOfForks( 5 ); + dto.setNumberOfKnifes( (short) 7 ); + dto.setNumberOfSpoons( (byte) 3 ); + dto.setApproximateKnifeLength( 3.7f ); + dto.setDrawerId( 1 ); + + CutleryInventoryEntity entity = CutleryInventoryMapper.INSTANCE.map( dto ); + assertThat( entity.getNumberOfForks() ).isEqualTo( 5L ); + assertThat( entity.getNumberOfKnifes() ).isEqualTo( 7 ); + assertThat( entity.getNumberOfSpoons() ).isEqualTo( (short) 3 ); + assertThat( entity.getApproximateKnifeLength() ).isCloseTo( 3.7d, withinPercentage( 0.0001d ) ); + assertThat( entity.getDrawerId() ).isEqualTo( "1" ); + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerMapper1.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerMapper1.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 24, + message = "Can't map property \"long numberOfForks\". It has a possibly lossy conversion from " + + "long to int.") + }) + public void testConversionFromLongToInt() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerOptionalMapper1.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerOptionalMapper1.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = "Can't map property \"OptionalLong numberOfForks\". It has a possibly lossy conversion from " + + "OptionalLong to int.") + }) + public void testConversionFromOptionalLongToInt() { + } + + @ProcessorTest + @WithClasses(KitchenDrawerMapper2.class) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = KitchenDrawerMapper2.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 24, + message = "property \"BigInteger numberOfKnifes\" has a possibly lossy conversion " + + "from BigInteger to Integer.") + }) + public void testConversionFromBigIntegerToInteger() { + } + + @ProcessorTest + @WithClasses(KitchenDrawerOptionalMapper2.class) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = KitchenDrawerOptionalMapper2.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 20, + message = "property \"Optional numberOfKnifes\" has a possibly lossy conversion " + + "from Optional to Integer.") + }) + public void testConversionFromOptionalBigIntegerToInteger() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerMapper6.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerMapper6.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Can't map property \"String drawerId\". It has a possibly lossy conversion from " + + "String to int.") + }) + public void testConversionFromStringToInt() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerOptionalMapper6.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerOptionalMapper6.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Can't map property \"Optional drawerId\". It has a possibly lossy conversion from " + + "Optional to int.") + }) + public void testConversionFromOptionalStringToInt() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerMapper3.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerMapper3.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 24, + message = "Can't map property \"VerySpecialNumber numberOfSpoons\". " + + "It has a possibly lossy conversion from BigInteger to Long.") + }) + public void test2StepConversionFromBigIntegerToLong() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerOptionalMapper3.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerOptionalMapper3.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = "Can't map property \"Optional numberOfSpoons\". " + + "It has a possibly lossy conversion from BigInteger to Long.") + }) + public void test2StepConversionFromOptionalBigIntegerToLong() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerMapper4.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerMapper4.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 24, + message = + "Can't map property \"Double depth\". It has a possibly lossy conversion from Double to float.") + }) + public void testConversionFromDoubleToFloat() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerOptionalMapper4.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerOptionalMapper4.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = + "Can't map property \"Optional depth\". " + + "It has a possibly lossy conversion from Optional to float.") + }) + public void testConversionFromOptionalDoubleToFloat() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerMapper5.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerMapper5.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 24, + message = + "Can't map property \"BigDecimal length\". It has a possibly lossy conversion from BigDecimal to Float.") + }) + public void testConversionFromBigDecimalToFloat() { + } + + @ProcessorTest + @WithClasses(ErroneousKitchenDrawerOptionalMapper5.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousKitchenDrawerOptionalMapper5.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = + "Can't map property \"Optional length\". " + + "It has a possibly lossy conversion from Optional to Float.") + }) + public void testConversionFromOptionalBigDecimalToFloat() { + } + + @ProcessorTest + @WithClasses(KitchenDrawerMapper6.class) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = KitchenDrawerMapper6.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 24, + message = "property \"double height\" has a possibly lossy conversion from double to float.") + }) + public void test2StepConversionFromDoubleToFloat() { + } + + @ProcessorTest + @WithClasses(KitchenDrawerOptionalMapper6.class) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = KitchenDrawerOptionalMapper6.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 20, + message = "property \"OptionalDouble height\" has a possibly lossy conversion from " + + "OptionalDouble to float.") + }) + public void test2StepConversionFromOptionalDoubleToFloat() { + } + + @ProcessorTest + @WithClasses(ListMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = ListMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 22, + message = "collection element has a possibly lossy conversion from BigDecimal to BigInteger.") + }) + public void testListElementConversion() { + } + + @ProcessorTest + @WithClasses(MapMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = MapMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 20, + message = "map key has a possibly lossy conversion from Long to Integer."), + @Diagnostic(type = MapMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 20, + message = "map value has a possibly lossy conversion from Double to Float.") + }) + public void testMapElementConversion() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/MapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/MapMapper.java new file mode 100644 index 0000000000..547971de43 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/MapMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * + * @author Sjaak Derksen + */ +@Mapper( typeConversionPolicy = ReportingPolicy.WARN ) +public interface MapMapper { + + Map map(Map in); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/OversizedKitchenDrawerDto.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/OversizedKitchenDrawerDto.java new file mode 100644 index 0000000000..c42b24cc57 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/OversizedKitchenDrawerDto.java @@ -0,0 +1,81 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import java.math.BigDecimal; +import java.math.BigInteger; + +/** + * + * @author Sjaak Derksen + */ +public class OversizedKitchenDrawerDto { + + /* yes, its a big drawer */ + private long numberOfForks; + private BigInteger numberOfKnifes; + private VerySpecialNumber numberOfSpoons; + private Double depth; + private BigDecimal length; + private double height; + private String drawerId; + + public long getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(long numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public BigInteger getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(BigInteger numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public VerySpecialNumber getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(VerySpecialNumber numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public Double getDepth() { + return depth; + } + + public void setDepth(Double depth) { + this.depth = depth; + } + + public BigDecimal getLength() { + return length; + } + + public void setLength(BigDecimal length) { + this.length = length; + } + + public double getHeight() { + return height; + } + + public void setHeight(double height) { + this.height = height; + } + + public String getDrawerId() { + return drawerId; + } + + public void setDrawerId(String drawerId) { + this.drawerId = drawerId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/OversizedKitchenDrawerOptionalDto.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/OversizedKitchenDrawerOptionalDto.java new file mode 100644 index 0000000000..f214fecd1d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/OversizedKitchenDrawerOptionalDto.java @@ -0,0 +1,84 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalLong; + +/** + * @author Filip Hrisafov + */ +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class OversizedKitchenDrawerOptionalDto { + + /* yes, its a big drawer */ + private OptionalLong numberOfForks; + private Optional numberOfKnifes; + private Optional numberOfSpoons; + private Optional depth; + private Optional length; + private OptionalDouble height; + private Optional drawerId; + + public OptionalLong getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(OptionalLong numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public Optional getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(Optional numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public Optional getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(Optional numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public Optional getDepth() { + return depth; + } + + public void setDepth(Optional depth) { + this.depth = depth; + } + + public Optional getLength() { + return length; + } + + public void setLength(Optional length) { + this.length = length; + } + + public OptionalDouble getHeight() { + return height; + } + + public void setHeight(OptionalDouble height) { + this.height = height; + } + + public Optional getDrawerId() { + return drawerId; + } + + public void setDrawerId(Optional drawerId) { + this.drawerId = drawerId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/RegularKitchenDrawerEntity.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/RegularKitchenDrawerEntity.java new file mode 100644 index 0000000000..e3ae10bc1f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/RegularKitchenDrawerEntity.java @@ -0,0 +1,77 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +/** + * + * @author Sjaak Derksen + */ +public class RegularKitchenDrawerEntity { + + private int numberOfForks; + private Integer numberOfKnifes; + private Long numberOfSpoons; + private float depth; + private Float length; + private VerySpecialNumber height; + private int drawerId; + + public int getNumberOfForks() { + return numberOfForks; + } + + public void setNumberOfForks(int numberOfForks) { + this.numberOfForks = numberOfForks; + } + + public Integer getNumberOfKnifes() { + return numberOfKnifes; + } + + public void setNumberOfKnifes(Integer numberOfKnifes) { + this.numberOfKnifes = numberOfKnifes; + } + + public Long getNumberOfSpoons() { + return numberOfSpoons; + } + + public void setNumberOfSpoons(Long numberOfSpoons) { + this.numberOfSpoons = numberOfSpoons; + } + + public float getDepth() { + return depth; + } + + public void setDepth(float depth) { + this.depth = depth; + } + + public Float getLength() { + return length; + } + + public void setLength(Float length) { + this.length = length; + } + + public VerySpecialNumber getHeight() { + return height; + } + + public void setHeight(VerySpecialNumber height) { + this.height = height; + } + + public int getDrawerId() { + return drawerId; + } + + public void setDrawerId(int drawerId) { + this.drawerId = drawerId; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/VerySpecialNumber.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/VerySpecialNumber.java new file mode 100644 index 0000000000..3f4be13d1f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/VerySpecialNumber.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +/** + * + * @author Sjaak Derksen + */ +public class VerySpecialNumber { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/VerySpecialNumberMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/VerySpecialNumberMapper.java new file mode 100644 index 0000000000..00b543c728 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/lossy/VerySpecialNumberMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.lossy; + +import java.math.BigInteger; +import java.util.Optional; + +/** + * @author Sjaak Derksen + */ +public class VerySpecialNumberMapper { + + VerySpecialNumber fromFloat(float f) { + return new VerySpecialNumber(); + } + + BigInteger toBigInteger(VerySpecialNumber v) { + return new BigInteger( "10" ); + } + + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") + BigInteger toBigInteger(Optional v) { + return new BigInteger( "10" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanConversionTest.java index 2572c99340..7c4035417b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanConversionTest.java @@ -1,40 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ BooleanSource.class, BooleanTarget.class, BooleanMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class BooleanConversionTest { - @Test + @ProcessorTest public void shouldApplyBooleanConversion() { BooleanSource source = new BooleanSource(); source.setB( true ); @@ -47,7 +31,7 @@ public void shouldApplyBooleanConversion() { assertThat( target.getBool() ).isEqualTo( Boolean.TRUE ); } - @Test + @ProcessorTest public void shouldApplyReverseBooleanConversion() { BooleanTarget target = new BooleanTarget(); target.setB( Boolean.TRUE ); @@ -60,9 +44,9 @@ public void shouldApplyReverseBooleanConversion() { assertThat( source.getBool() ).isEqualTo( true ); } - @Test + @ProcessorTest @IssueKey( "229" ) - public void wrapperToPrimitveIsNullSafe() { + public void wrapperToPrimitiveIsNullSafe() { BooleanTarget target = new BooleanTarget(); BooleanSource source = BooleanMapper.INSTANCE.targetToSource( target ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanMapper.java index 80615d8443..6765df6ace 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanSource.java index 5832578788..e5b6f0aad0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanTarget.java index 95a091af28..c9a1019c0b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/BooleanTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteSource.java index c762912138..2f647027ed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteTarget.java index b9006d8b3b..3ec43ebf2f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperOptionalSource.java new file mode 100644 index 0000000000..a92b029b14 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class ByteWrapperOptionalSource { + + private Optional b = Optional.empty(); + private Optional bb = Optional.empty(); + private Optional s = Optional.empty(); + private Optional ss = Optional.empty(); + private Optional i = Optional.empty(); + private Optional ii = Optional.empty(); + private Optional l = Optional.empty(); + private Optional ll = Optional.empty(); + private Optional f = Optional.empty(); + private Optional ff = Optional.empty(); + private Optional d = Optional.empty(); + private Optional dd = Optional.empty(); + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperSource.java index 8a8292c64b..e7dbe2c06b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperTarget.java index 010c2c6a74..643ec19871 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ByteWrapperTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharConversionTest.java index 80cafea743..def3b45ac5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharConversionTest.java @@ -1,40 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ CharSource.class, CharTarget.class, CharMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class CharConversionTest { - @Test + @ProcessorTest public void shouldApplyCharConversion() { CharSource source = new CharSource(); source.setC( 'G' ); @@ -45,10 +29,10 @@ public void shouldApplyCharConversion() { assertThat( target.getC() ).isEqualTo( Character.valueOf( 'G' ) ); } - @Test + @ProcessorTest public void shouldApplyReverseCharConversion() { CharTarget target = new CharTarget(); - target.setC( Character.valueOf( 'G' ) ); + target.setC( 'G' ); CharSource source = CharMapper.INSTANCE.targetToSource( target ); @@ -56,9 +40,9 @@ public void shouldApplyReverseCharConversion() { assertThat( source.getC() ).isEqualTo( 'G' ); } - @Test + @ProcessorTest @IssueKey( "229" ) - public void wrapperToPrimitveIsNullSafe() { + public void wrapperToPrimitiveIsNullSafe() { CharTarget target = new CharTarget(); CharSource source = CharMapper.INSTANCE.targetToSource( target ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharMapper.java index fdf7d48bcc..fabdb78392 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharSource.java index 9593524f7c..450c2c467c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharTarget.java index c74cef64ab..324d43a0ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/CharTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleOptionalSource.java new file mode 100644 index 0000000000..e469c44390 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.OptionalDouble; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class DoubleOptionalSource { + + private OptionalDouble b = OptionalDouble.empty(); + private OptionalDouble bb = OptionalDouble.empty(); + private OptionalDouble s = OptionalDouble.empty(); + private OptionalDouble ss = OptionalDouble.empty(); + private OptionalDouble i = OptionalDouble.empty(); + private OptionalDouble ii = OptionalDouble.empty(); + private OptionalDouble l = OptionalDouble.empty(); + private OptionalDouble ll = OptionalDouble.empty(); + private OptionalDouble f = OptionalDouble.empty(); + private OptionalDouble ff = OptionalDouble.empty(); + private OptionalDouble d = OptionalDouble.empty(); + private OptionalDouble dd = OptionalDouble.empty(); + + public OptionalDouble getB() { + return b; + } + + public void setB(OptionalDouble b) { + this.b = b; + } + + public OptionalDouble getBb() { + return bb; + } + + public void setBb(OptionalDouble bb) { + this.bb = bb; + } + + public OptionalDouble getS() { + return s; + } + + public void setS(OptionalDouble s) { + this.s = s; + } + + public OptionalDouble getSs() { + return ss; + } + + public void setSs(OptionalDouble ss) { + this.ss = ss; + } + + public OptionalDouble getI() { + return i; + } + + public void setI(OptionalDouble i) { + this.i = i; + } + + public OptionalDouble getIi() { + return ii; + } + + public void setIi(OptionalDouble ii) { + this.ii = ii; + } + + public OptionalDouble getL() { + return l; + } + + public void setL(OptionalDouble l) { + this.l = l; + } + + public OptionalDouble getLl() { + return ll; + } + + public void setLl(OptionalDouble ll) { + this.ll = ll; + } + + public OptionalDouble getF() { + return f; + } + + public void setF(OptionalDouble f) { + this.f = f; + } + + public OptionalDouble getFf() { + return ff; + } + + public void setFf(OptionalDouble ff) { + this.ff = ff; + } + + public OptionalDouble getD() { + return d; + } + + public void setD(OptionalDouble d) { + this.d = d; + } + + public OptionalDouble getDd() { + return dd; + } + + public void setDd(OptionalDouble dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleSource.java index 90ce2f320a..f061bae18b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleTarget.java index 88e875472c..62bcb28716 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperOptionalSource.java new file mode 100644 index 0000000000..ecf0d9bc41 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class DoubleWrapperOptionalSource { + + private Optional b = Optional.empty(); + private Optional bb = Optional.empty(); + private Optional s = Optional.empty(); + private Optional ss = Optional.empty(); + private Optional i = Optional.empty(); + private Optional ii = Optional.empty(); + private Optional l = Optional.empty(); + private Optional ll = Optional.empty(); + private Optional f = Optional.empty(); + private Optional ff = Optional.empty(); + private Optional d = Optional.empty(); + private Optional dd = Optional.empty(); + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperSource.java index 3565ec000f..74c9267db7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperTarget.java index 56a5ebd8bf..c3584f7083 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/DoubleWrapperTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatSource.java index 33e1398201..0a3ca13a3d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatTarget.java index de2e5f2eac..f2c7dfe837 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperOptionalSource.java new file mode 100644 index 0000000000..f20e6fa5d9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class FloatWrapperOptionalSource { + + private Optional b = Optional.empty(); + private Optional bb = Optional.empty(); + private Optional s = Optional.empty(); + private Optional ss = Optional.empty(); + private Optional i = Optional.empty(); + private Optional ii = Optional.empty(); + private Optional l = Optional.empty(); + private Optional ll = Optional.empty(); + private Optional f = Optional.empty(); + private Optional ff = Optional.empty(); + private Optional d = Optional.empty(); + private Optional dd = Optional.empty(); + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperSource.java index 78698d328a..1033aa317e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperTarget.java index 8b4ab38f33..d9e3deef65 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/FloatWrapperTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntOptionalSource.java new file mode 100644 index 0000000000..6543b7bc0b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.OptionalInt; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class IntOptionalSource { + + private OptionalInt b = OptionalInt.empty(); + private OptionalInt bb = OptionalInt.empty(); + private OptionalInt s = OptionalInt.empty(); + private OptionalInt ss = OptionalInt.empty(); + private OptionalInt i = OptionalInt.empty(); + private OptionalInt ii = OptionalInt.empty(); + private OptionalInt l = OptionalInt.empty(); + private OptionalInt ll = OptionalInt.empty(); + private OptionalInt f = OptionalInt.empty(); + private OptionalInt ff = OptionalInt.empty(); + private OptionalInt d = OptionalInt.empty(); + private OptionalInt dd = OptionalInt.empty(); + + public OptionalInt getB() { + return b; + } + + public void setB(OptionalInt b) { + this.b = b; + } + + public OptionalInt getBb() { + return bb; + } + + public void setBb(OptionalInt bb) { + this.bb = bb; + } + + public OptionalInt getS() { + return s; + } + + public void setS(OptionalInt s) { + this.s = s; + } + + public OptionalInt getSs() { + return ss; + } + + public void setSs(OptionalInt ss) { + this.ss = ss; + } + + public OptionalInt getI() { + return i; + } + + public void setI(OptionalInt i) { + this.i = i; + } + + public OptionalInt getIi() { + return ii; + } + + public void setIi(OptionalInt ii) { + this.ii = ii; + } + + public OptionalInt getL() { + return l; + } + + public void setL(OptionalInt l) { + this.l = l; + } + + public OptionalInt getLl() { + return ll; + } + + public void setLl(OptionalInt ll) { + this.ll = ll; + } + + public OptionalInt getF() { + return f; + } + + public void setF(OptionalInt f) { + this.f = f; + } + + public OptionalInt getFf() { + return ff; + } + + public void setFf(OptionalInt ff) { + this.ff = ff; + } + + public OptionalInt getD() { + return d; + } + + public void setD(OptionalInt d) { + this.d = d; + } + + public OptionalInt getDd() { + return dd; + } + + public void setDd(OptionalInt dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntSource.java index d804202ba0..de2143fe6d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntTarget.java index 2b8b9fe2fc..1e0c4a558d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperOptionalSource.java new file mode 100644 index 0000000000..b1243d9c1c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class IntWrapperOptionalSource { + + private Optional b = Optional.empty(); + private Optional bb = Optional.empty(); + private Optional s = Optional.empty(); + private Optional ss = Optional.empty(); + private Optional i = Optional.empty(); + private Optional ii = Optional.empty(); + private Optional l = Optional.empty(); + private Optional ll = Optional.empty(); + private Optional f = Optional.empty(); + private Optional ff = Optional.empty(); + private Optional d = Optional.empty(); + private Optional dd = Optional.empty(); + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperSource.java index b22fcd3717..8912a8f592 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperTarget.java index f7a568fff7..3b8d6a0044 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/IntWrapperTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongOptionalSource.java new file mode 100644 index 0000000000..1df7baaec9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.OptionalLong; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class LongOptionalSource { + + private OptionalLong b = OptionalLong.empty(); + private OptionalLong bb = OptionalLong.empty(); + private OptionalLong s = OptionalLong.empty(); + private OptionalLong ss = OptionalLong.empty(); + private OptionalLong i = OptionalLong.empty(); + private OptionalLong ii = OptionalLong.empty(); + private OptionalLong l = OptionalLong.empty(); + private OptionalLong ll = OptionalLong.empty(); + private OptionalLong f = OptionalLong.empty(); + private OptionalLong ff = OptionalLong.empty(); + private OptionalLong d = OptionalLong.empty(); + private OptionalLong dd = OptionalLong.empty(); + + public OptionalLong getB() { + return b; + } + + public void setB(OptionalLong b) { + this.b = b; + } + + public OptionalLong getBb() { + return bb; + } + + public void setBb(OptionalLong bb) { + this.bb = bb; + } + + public OptionalLong getS() { + return s; + } + + public void setS(OptionalLong s) { + this.s = s; + } + + public OptionalLong getSs() { + return ss; + } + + public void setSs(OptionalLong ss) { + this.ss = ss; + } + + public OptionalLong getI() { + return i; + } + + public void setI(OptionalLong i) { + this.i = i; + } + + public OptionalLong getIi() { + return ii; + } + + public void setIi(OptionalLong ii) { + this.ii = ii; + } + + public OptionalLong getL() { + return l; + } + + public void setL(OptionalLong l) { + this.l = l; + } + + public OptionalLong getLl() { + return ll; + } + + public void setLl(OptionalLong ll) { + this.ll = ll; + } + + public OptionalLong getF() { + return f; + } + + public void setF(OptionalLong f) { + this.f = f; + } + + public OptionalLong getFf() { + return ff; + } + + public void setFf(OptionalLong ff) { + this.ff = ff; + } + + public OptionalLong getD() { + return d; + } + + public void setD(OptionalLong d) { + this.d = d; + } + + public OptionalLong getDd() { + return dd; + } + + public void setDd(OptionalLong dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongSource.java index d7e5b100ae..710bc58172 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongTarget.java index 1252467848..7d1f35b23d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperOptionalSource.java new file mode 100644 index 0000000000..bed8ab6b59 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class LongWrapperOptionalSource { + + private Optional b = Optional.empty(); + private Optional bb = Optional.empty(); + private Optional s = Optional.empty(); + private Optional ss = Optional.empty(); + private Optional i = Optional.empty(); + private Optional ii = Optional.empty(); + private Optional l = Optional.empty(); + private Optional ll = Optional.empty(); + private Optional f = Optional.empty(); + private Optional ff = Optional.empty(); + private Optional d = Optional.empty(); + private Optional dd = Optional.empty(); + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperSource.java index 093667e589..9c876f7c1e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperTarget.java index d5844e042a..8a6218fa5b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/LongWrapperTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberConversionTest.java index 2579bfc550..61be21e797 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberConversionTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ ByteSource.class, @@ -53,10 +38,9 @@ DoubleWrapperTarget.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class NumberConversionTest { - @Test + @ProcessorTest public void shouldApplyByteConversions() { ByteSource source = new ByteSource(); source.setB( (byte) 1 ); @@ -89,7 +73,7 @@ public void shouldApplyByteConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyByteWrapperConversions() { ByteWrapperSource source = new ByteWrapperSource(); source.setB( (byte) 1 ); @@ -122,7 +106,7 @@ public void shouldApplyByteWrapperConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyShortConversions() { ShortSource source = new ShortSource(); source.setB( (short) 1 ); @@ -155,7 +139,7 @@ public void shouldApplyShortConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyShortWrapperConversions() { ShortWrapperSource source = new ShortWrapperSource(); source.setB( (short) 1 ); @@ -188,7 +172,7 @@ public void shouldApplyShortWrapperConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyIntConversions() { IntSource source = new IntSource(); source.setB( 1 ); @@ -221,7 +205,7 @@ public void shouldApplyIntConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyIntWrapperConversions() { IntWrapperSource source = new IntWrapperSource(); source.setB( 1 ); @@ -254,7 +238,7 @@ public void shouldApplyIntWrapperConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyLongConversions() { LongSource source = new LongSource(); source.setB( 1 ); @@ -287,7 +271,7 @@ public void shouldApplyLongConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyLongWrapperConversions() { LongWrapperSource source = new LongWrapperSource(); source.setB( (long) 1 ); @@ -320,7 +304,7 @@ public void shouldApplyLongWrapperConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyFloatConversions() { FloatSource source = new FloatSource(); source.setB( 1 ); @@ -353,7 +337,7 @@ public void shouldApplyFloatConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyFloatWrapperConversions() { FloatWrapperSource source = new FloatWrapperSource(); source.setB( 1f ); @@ -386,7 +370,7 @@ public void shouldApplyFloatWrapperConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyDoubleConversions() { DoubleSource source = new DoubleSource(); source.setB( 1 ); @@ -419,7 +403,7 @@ public void shouldApplyDoubleConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest public void shouldApplyDoubleWrapperConversions() { DoubleWrapperSource source = new DoubleWrapperSource(); source.setB( 1d ); @@ -452,9 +436,9 @@ public void shouldApplyDoubleWrapperConversions() { assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); } - @Test + @ProcessorTest @IssueKey( "229" ) - public void wrapperToPrimitveIsNullSafe() { + public void wrapperToPrimitiveIsNullSafe() { assertThat( SourceTargetMapper.INSTANCE.sourceToTarget( new ByteWrapperSource() ) ).isNotNull(); assertThat( SourceTargetMapper.INSTANCE.sourceToTarget( new DoubleWrapperSource() ) ).isNotNull(); assertThat( SourceTargetMapper.INSTANCE.sourceToTarget( new ShortWrapperSource() ) ).isNotNull(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberOptionalConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberOptionalConversionTest.java new file mode 100644 index 0000000000..0857b20473 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/NumberOptionalConversionTest.java @@ -0,0 +1,357 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; +import java.util.OptionalDouble; +import java.util.OptionalInt; +import java.util.OptionalLong; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + ByteTarget.class, + ByteWrapperOptionalSource.class, + ByteWrapperTarget.class, + ShortTarget.class, + ShortWrapperOptionalSource.class, + ShortWrapperTarget.class, + IntOptionalSource.class, + IntTarget.class, + IntWrapperOptionalSource.class, + IntWrapperTarget.class, + LongOptionalSource.class, + LongTarget.class, + LongWrapperOptionalSource.class, + LongWrapperTarget.class, + FloatWrapperOptionalSource.class, + FloatWrapperTarget.class, + DoubleOptionalSource.class, + DoubleTarget.class, + DoubleWrapperOptionalSource.class, + DoubleWrapperTarget.class, + OptionalNumberConversionMapper.class +}) +public class NumberOptionalConversionTest { + + @ProcessorTest + public void shouldApplyByteWrapperConversions() { + ByteWrapperOptionalSource source = new ByteWrapperOptionalSource(); + source.setB( Optional.of( (byte) 1 ) ); + source.setBb( Optional.of( (byte) 2 ) ); + source.setS( Optional.of( (byte) 3 ) ); + source.setSs( Optional.of( (byte) 4 ) ); + source.setI( Optional.of( (byte) 5 ) ); + source.setIi( Optional.of( (byte) 6 ) ); + source.setL( Optional.of( (byte) 7 ) ); + source.setLl( Optional.of( (byte) 8 ) ); + source.setF( Optional.of( (byte) 9 ) ); + source.setFf( Optional.of( (byte) 10 ) ); + source.setD( Optional.of( (byte) 11 ) ); + source.setDd( Optional.of( (byte) 12 ) ); + + ByteWrapperTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyShortWrapperConversions() { + ShortWrapperOptionalSource source = new ShortWrapperOptionalSource(); + source.setB( Optional.of( (short) 1 ) ); + source.setBb( Optional.of( (short) 2 ) ); + source.setS( Optional.of( (short) 3 ) ); + source.setSs( Optional.of( (short) 4 ) ); + source.setI( Optional.of( (short) 5 ) ); + source.setIi( Optional.of( (short) 6 ) ); + source.setL( Optional.of( (short) 7 ) ); + source.setLl( Optional.of( (short) 8 ) ); + source.setF( Optional.of( (short) 9 ) ); + source.setFf( Optional.of( (short) 10 ) ); + source.setD( Optional.of( (short) 11 ) ); + source.setDd( Optional.of( (short) 12 ) ); + + ShortWrapperTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyIntConversions() { + IntOptionalSource source = new IntOptionalSource(); + source.setB( OptionalInt.of( 1 ) ); + source.setBb( OptionalInt.of( 2 ) ); + source.setS( OptionalInt.of( 3 ) ); + source.setSs( OptionalInt.of( 4 ) ); + source.setI( OptionalInt.of( 5 ) ); + source.setIi( OptionalInt.of( 6 ) ); + source.setL( OptionalInt.of( 7 ) ); + source.setLl( OptionalInt.of( 8 ) ); + source.setF( OptionalInt.of( 9 ) ); + source.setFf( OptionalInt.of( 10 ) ); + source.setD( OptionalInt.of( 11 ) ); + source.setDd( OptionalInt.of( 12 ) ); + + IntTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyIntWrapperConversions() { + IntWrapperOptionalSource source = new IntWrapperOptionalSource(); + source.setB( Optional.of( 1 ) ); + source.setBb( Optional.of( 2 ) ); + source.setS( Optional.of( 3 ) ); + source.setSs( Optional.of( 4 ) ); + source.setI( Optional.of( 5 ) ); + source.setIi( Optional.of( 6 ) ); + source.setL( Optional.of( 7 ) ); + source.setLl( Optional.of( 8 ) ); + source.setF( Optional.of( 9 ) ); + source.setFf( Optional.of( 10 ) ); + source.setD( Optional.of( 11 ) ); + source.setDd( Optional.of( 12 ) ); + + IntWrapperTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyLongConversions() { + LongOptionalSource source = new LongOptionalSource(); + source.setB( OptionalLong.of( 1 ) ); + source.setBb( OptionalLong.of( 2 ) ); + source.setS( OptionalLong.of( 3 ) ); + source.setSs( OptionalLong.of( 4 ) ); + source.setI( OptionalLong.of( 5 ) ); + source.setIi( OptionalLong.of( 6 ) ); + source.setL( OptionalLong.of( 7 ) ); + source.setLl( OptionalLong.of( 8 ) ); + source.setF( OptionalLong.of( 9 ) ); + source.setFf( OptionalLong.of( 10 ) ); + source.setD( OptionalLong.of( 11 ) ); + source.setDd( OptionalLong.of( 12 ) ); + + LongTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyLongWrapperConversions() { + LongWrapperOptionalSource source = new LongWrapperOptionalSource(); + source.setB( Optional.of( (long) 1 ) ); + source.setBb( Optional.of( (long) 2 ) ); + source.setS( Optional.of( (long) 3 ) ); + source.setSs( Optional.of( (long) 4 ) ); + source.setI( Optional.of( (long) 5 ) ); + source.setIi( Optional.of( (long) 6 ) ); + source.setL( Optional.of( (long) 7 ) ); + source.setLl( Optional.of( (long) 8 ) ); + source.setF( Optional.of( (long) 9 ) ); + source.setFf( Optional.of( (long) 10 ) ); + source.setD( Optional.of( (long) 11 ) ); + source.setDd( Optional.of( (long) 12 ) ); + + LongWrapperTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyFloatWrapperConversions() { + FloatWrapperOptionalSource source = new FloatWrapperOptionalSource(); + source.setB( Optional.of( 1f ) ); + source.setBb( Optional.of( 2f ) ); + source.setS( Optional.of( 3f ) ); + source.setSs( Optional.of( 4f ) ); + source.setI( Optional.of( 5f ) ); + source.setIi( Optional.of( 6f ) ); + source.setL( Optional.of( 7f ) ); + source.setLl( Optional.of( 8f ) ); + source.setF( Optional.of( 9f ) ); + source.setFf( Optional.of( 10f ) ); + source.setD( Optional.of( 11f ) ); + source.setDd( Optional.of( 12f ) ); + + FloatWrapperTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyDoubleConversions() { + DoubleOptionalSource source = new DoubleOptionalSource(); + source.setB( OptionalDouble.of( 1 ) ); + source.setBb( OptionalDouble.of( 2 ) ); + source.setS( OptionalDouble.of( 3 ) ); + source.setSs( OptionalDouble.of( 4 ) ); + source.setI( OptionalDouble.of( 5 ) ); + source.setIi( OptionalDouble.of( 6 ) ); + source.setL( OptionalDouble.of( 7 ) ); + source.setLl( OptionalDouble.of( 8 ) ); + source.setF( OptionalDouble.of( 9 ) ); + source.setFf( OptionalDouble.of( 10 ) ); + source.setD( OptionalDouble.of( 11 ) ); + source.setDd( OptionalDouble.of( 12 ) ); + + DoubleTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + public void shouldApplyDoubleWrapperConversions() { + DoubleWrapperOptionalSource source = new DoubleWrapperOptionalSource(); + source.setB( Optional.of( 1d ) ); + source.setBb( Optional.of( 2d ) ); + source.setS( Optional.of( 3d ) ); + source.setSs( Optional.of( 4d ) ); + source.setI( Optional.of( 5d ) ); + source.setIi( Optional.of( 6d ) ); + source.setL( Optional.of( 7d ) ); + source.setLl( Optional.of( 8d ) ); + source.setF( Optional.of( 9d ) ); + source.setFf( Optional.of( 10d ) ); + source.setD( Optional.of( 11d ) ); + source.setDd( Optional.of( 12d ) ); + + DoubleWrapperTarget target = OptionalNumberConversionMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( (byte) 1 ); + assertThat( target.getBb() ).isEqualTo( Byte.valueOf( (byte) 2 ) ); + assertThat( target.getS() ).isEqualTo( (short) 3 ); + assertThat( target.getSs() ).isEqualTo( Short.valueOf( (short) 4 ) ); + assertThat( target.getI() ).isEqualTo( 5 ); + assertThat( target.getIi() ).isEqualTo( Integer.valueOf( 6 ) ); + assertThat( target.getL() ).isEqualTo( 7 ); + assertThat( target.getLl() ).isEqualTo( Long.valueOf( 8 ) ); + assertThat( target.getF() ).isEqualTo( 9f ); + assertThat( target.getFf() ).isEqualTo( Float.valueOf( 10f ) ); + assertThat( target.getD() ).isEqualTo( 11d ); + assertThat( target.getDd() ).isEqualTo( Double.valueOf( 12d ) ); + } + + @ProcessorTest + @IssueKey("229") + public void wrapperToPrimitiveIsNullSafe() { + assertThat( OptionalNumberConversionMapper.INSTANCE.sourceToTarget( new ByteWrapperOptionalSource() ) ) + .isNotNull(); + assertThat( OptionalNumberConversionMapper.INSTANCE.sourceToTarget( new DoubleWrapperOptionalSource() ) ) + .isNotNull(); + assertThat( OptionalNumberConversionMapper.INSTANCE.sourceToTarget( new ShortWrapperOptionalSource() ) ) + .isNotNull(); + assertThat( OptionalNumberConversionMapper.INSTANCE.sourceToTarget( new IntWrapperOptionalSource() ) ) + .isNotNull(); + assertThat( OptionalNumberConversionMapper.INSTANCE.sourceToTarget( new FloatWrapperOptionalSource() ) ) + .isNotNull(); + assertThat( OptionalNumberConversionMapper.INSTANCE.sourceToTarget( new LongWrapperOptionalSource() ) ) + .isNotNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/OptionalNumberConversionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/OptionalNumberConversionMapper.java new file mode 100644 index 0000000000..94472586fa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/OptionalNumberConversionMapper.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface OptionalNumberConversionMapper { + + OptionalNumberConversionMapper INSTANCE = Mappers.getMapper( OptionalNumberConversionMapper.class ); + + ByteWrapperTarget sourceToTarget(ByteWrapperOptionalSource source); + + ByteWrapperOptionalSource targetToSource(ByteWrapperTarget target); + + ShortWrapperTarget sourceToTarget(ShortWrapperOptionalSource source); + + ShortWrapperOptionalSource targetToSource(ShortWrapperTarget target); + + IntTarget sourceToTarget(IntOptionalSource source); + + IntOptionalSource targetToSource(IntTarget target); + + IntWrapperTarget sourceToTarget(IntWrapperOptionalSource source); + + IntWrapperOptionalSource targetToSource(IntWrapperTarget target); + + LongTarget sourceToTarget(LongOptionalSource source); + + LongOptionalSource targetToSource(LongTarget target); + + LongWrapperTarget sourceToTarget(LongWrapperOptionalSource source); + + LongWrapperOptionalSource targetToSource(LongWrapperTarget target); + + FloatWrapperTarget sourceToTarget(FloatWrapperOptionalSource source); + + FloatWrapperOptionalSource targetToSource(FloatWrapperTarget target); + + DoubleTarget sourceToTarget(DoubleOptionalSource source); + + DoubleOptionalSource targetToSource(DoubleTarget target); + + DoubleWrapperTarget sourceToTarget(DoubleWrapperOptionalSource source); + + DoubleWrapperOptionalSource targetToSource(DoubleWrapperTarget target); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortSource.java index 1ba02c15e7..cf88274634 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortTarget.java index e820c6fe9d..bd5635d07a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperOptionalSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperOptionalSource.java new file mode 100644 index 0000000000..16acf6c69b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperOptionalSource.java @@ -0,0 +1,121 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.nativetypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class ShortWrapperOptionalSource { + + private Optional b = Optional.empty(); + private Optional bb = Optional.empty(); + private Optional s = Optional.empty(); + private Optional ss = Optional.empty(); + private Optional i = Optional.empty(); + private Optional ii = Optional.empty(); + private Optional l = Optional.empty(); + private Optional ll = Optional.empty(); + private Optional f = Optional.empty(); + private Optional ff = Optional.empty(); + private Optional d = Optional.empty(); + private Optional dd = Optional.empty(); + + public Optional getB() { + return b; + } + + public void setB(Optional b) { + this.b = b; + } + + public Optional getBb() { + return bb; + } + + public void setBb(Optional bb) { + this.bb = bb; + } + + public Optional getS() { + return s; + } + + public void setS(Optional s) { + this.s = s; + } + + public Optional getSs() { + return ss; + } + + public void setSs(Optional ss) { + this.ss = ss; + } + + public Optional getI() { + return i; + } + + public void setI(Optional i) { + this.i = i; + } + + public Optional getIi() { + return ii; + } + + public void setIi(Optional ii) { + this.ii = ii; + } + + public Optional getL() { + return l; + } + + public void setL(Optional l) { + this.l = l; + } + + public Optional getLl() { + return ll; + } + + public void setLl(Optional ll) { + this.ll = ll; + } + + public Optional getF() { + return f; + } + + public void setF(Optional f) { + this.f = f; + } + + public Optional getFf() { + return ff; + } + + public void setFf(Optional ff) { + this.ff = ff; + } + + public Optional getD() { + return d; + } + + public void setD(Optional d) { + this.d = d; + } + + public Optional getDd() { + return dd; + } + + public void setDd(Optional dd) { + this.dd = dd; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperSource.java index c72f3a7947..9a52592df9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperTarget.java index a1dc1367a7..4093f3988c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/ShortWrapperTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/SourceTargetMapper.java index eb2acff75f..8e4f51b9c7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/nativetypes/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.nativetypes; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/NumberFormatConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/NumberFormatConversionTest.java index 6ef67611a2..39b4e98319 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/NumberFormatConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/NumberFormatConversionTest.java @@ -1,37 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.numbers; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; - import java.math.BigDecimal; import java.math.BigInteger; -import java.util.Arrays; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junitpioneer.jupiter.DefaultLocale; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.entry; @@ -40,15 +25,14 @@ Target.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) +@DefaultLocale("en") public class NumberFormatConversionTest { - @Before - public void setDefaultLocale() { - Locale.setDefault( Locale.ENGLISH ); - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource() + .addComparisonToFixtureFor( SourceTargetMapper.class ); - @Test + @ProcessorTest public void shouldApplyStringConversions() { Source source = new Source(); source.setI( 1 ); @@ -89,7 +73,48 @@ public void shouldApplyStringConversions() { assertThat( target.getBigInteger1() ).isEqualTo( "1.23456789E12" ); } - @Test + @ProcessorTest + public void shouldApplyStringConversionsWithCustomLocale() { + Source source = new Source(); + source.setI( 1 ); + source.setIi( 2 ); + source.setD( 3.0 ); + source.setDd( 4.0 ); + source.setF( 3.0f ); + source.setFf( 4.0f ); + source.setL( 5L ); + source.setLl( 6L ); + source.setB( (byte) 7 ); + source.setBb( (byte) 8 ); + + source.setComplex1( 345346.456756 ); + source.setComplex2( 5007034.3 ); + + source.setBigDecimal1( new BigDecimal( "987E-20" ) ); + source.setBigInteger1( new BigInteger( "1234567890000" ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTargetWithCustomLocale( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getI() ).isEqualTo( "1.00" ); + assertThat( target.getIi() ).isEqualTo( "2.00" ); + assertThat( target.getD() ).isEqualTo( "3.00" ); + assertThat( target.getDd() ).isEqualTo( "4.00" ); + assertThat( target.getF() ).isEqualTo( "3.00" ); + assertThat( target.getFf() ).isEqualTo( "4.00" ); + assertThat( target.getL() ).isEqualTo( "5.00" ); + assertThat( target.getLl() ).isEqualTo( "6.00" ); + assertThat( target.getB() ).isEqualTo( "7.00" ); + assertThat( target.getBb() ).isEqualTo( "8.00" ); + + assertThat( target.getComplex1() ).isEqualTo( "345.35E3" ); + assertThat( target.getComplex2() ).isEqualTo( "$5007034.30" ); + + assertThat( target.getBigDecimal1() ).isEqualTo( "9,87E-18" ); + assertThat( target.getBigInteger1() ).isEqualTo( "1,23456789E12" ); + } + + @ProcessorTest public void shouldApplyReverseStringConversions() { Target target = new Target(); target.setI( "1.00" ); @@ -130,23 +155,79 @@ public void shouldApplyReverseStringConversions() { assertThat( source.getBigInteger1() ).isEqualTo( new BigInteger( "1234567890000" ) ); } - @Test + @ProcessorTest + public void shouldApplyReverseStringConversionsWithCustomLocale() { + Target target = new Target(); + target.setI( "1.00" ); + target.setIi( "2.00" ); + target.setD( "3.00" ); + target.setDd( "4.00" ); + target.setF( "3.00" ); + target.setFf( "4.00" ); + target.setL( "5.00" ); + target.setLl( "6.00" ); + target.setB( "7.00" ); + target.setBb( "8.00" ); + + target.setComplex1( "345.35E3" ); + target.setComplex2( "$5007034.30" ); + + target.setBigDecimal1( "9,87E-18" ); + target.setBigInteger1( "1,23456789E12" ); + + Source source = SourceTargetMapper.INSTANCE.targetToSourceWithCustomLocale( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getI() ).isEqualTo( 1 ); + assertThat( source.getIi() ).isEqualTo( Integer.valueOf( 2 ) ); + assertThat( source.getD() ).isEqualTo( 3.0 ); + assertThat( source.getDd() ).isEqualTo( Double.valueOf( 4.0 ) ); + assertThat( source.getF() ).isEqualTo( 3.0f ); + assertThat( source.getFf() ).isEqualTo( Float.valueOf( 4.0f ) ); + assertThat( source.getL() ).isEqualTo( 5L ); + assertThat( source.getLl() ).isEqualTo( Long.valueOf( 6L ) ); + assertThat( source.getB() ).isEqualTo( (byte) 7 ); + assertThat( source.getBb() ).isEqualTo( (byte) 8 ); + + assertThat( source.getComplex1() ).isEqualTo( 345350.0 ); + assertThat( source.getComplex2() ).isEqualTo( 5007034.3 ); + + assertThat( source.getBigDecimal1() ).isEqualTo( new BigDecimal( "987E-20" ) ); + assertThat( source.getBigInteger1() ).isEqualTo( new BigInteger( "1234567890000" ) ); + } + + @ProcessorTest public void shouldApplyStringConversionsToIterables() { - List target = SourceTargetMapper.INSTANCE.sourceToTarget( Arrays.asList( 2f ) ); + List target = SourceTargetMapper.INSTANCE.sourceToTarget( List.of( 2f ) ); assertThat( target ).hasSize( 1 ); - assertThat( target ).isEqualTo( Arrays.asList( "2.00" ) ); + assertThat( target ).isEqualTo( List.of( "2.00" ) ); List source = SourceTargetMapper.INSTANCE.targetToSource( target ); assertThat( source ).hasSize( 1 ); - assertThat( source ).isEqualTo( Arrays.asList( 2.00f ) ); + assertThat( source ).isEqualTo( List.of( 2.00f ) ); } - @Test + @ProcessorTest + public void shouldApplyStringConversionsToIterablesWithCustomLocale() { + + List target = SourceTargetMapper.INSTANCE.sourceToTargetWithCustomLocale( + List.of( new BigDecimal("987E-20") ) + ); + + assertThat( target ).hasSize( 1 ); + assertThat( target ).isEqualTo( List.of( "9,87E-18" ) ); + + List source = SourceTargetMapper.INSTANCE.targetToSourceWithCustomLocale( target ); + assertThat( source ).hasSize( 1 ); + assertThat( source ).isEqualTo( List.of( new BigDecimal("987E-20") ) ); + } + + @ProcessorTest public void shouldApplyStringConversionsToMaps() { - Map source1 = new HashMap(); + Map source1 = new HashMap<>(); source1.put( 1.0001f, 2.01f ); Map target = SourceTargetMapper.INSTANCE.sourceToTarget( source1 ); @@ -158,4 +239,20 @@ public void shouldApplyStringConversionsToMaps() { assertThat( source2 ).contains( entry( 1.00f, 2f ) ); } + + @ProcessorTest + public void shouldApplyStringConversionsToMapsWithCustomLocale() { + + Map source1 = new HashMap<>(); + source1.put( new BigDecimal( "987E-20" ), new BigDecimal( "97E-10" ) ); + + Map target = SourceTargetMapper.INSTANCE.sourceToTargetWithCustomLocale( source1 ); + assertThat( target ).hasSize( 1 ); + assertThat( target ).contains( entry( "9,87E-18", "9,7E-9" ) ); + + Map source2 = SourceTargetMapper.INSTANCE.targetToSourceWithCustomLocale( target ); + assertThat( source2 ).hasSize( 1 ); + assertThat( source2 ).contains( entry( new BigDecimal( "987E-20" ), new BigDecimal( "97E-10" ) ) ); + + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Source.java index d9989bcd7d..96f9a704b9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.numbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/SourceTargetMapper.java index e283e3c60f..70b16970c6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/SourceTargetMapper.java @@ -1,25 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.numbers; +import java.math.BigDecimal; import java.util.List; import java.util.Map; + import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.IterableMapping; import org.mapstruct.MapMapping; @@ -54,21 +43,55 @@ public interface SourceTargetMapper { } ) Target sourceToTarget(Source source); - @InheritInverseConfiguration + @Mappings( { + @Mapping( target = "i", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "ii", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "d", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "dd", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "f", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "ff", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "l", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "ll", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "b", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "bb", numberFormat = NUMBER_FORMAT, locale = "ru" ), + @Mapping( target = "complex1", numberFormat = "##0.##E0", locale = "ru" ), + @Mapping( target = "complex2", numberFormat = "$#.00", locale = "ru" ), + @Mapping( target = "bigDecimal1", numberFormat = "#0.#E0", locale = "ru" ), + @Mapping( target = "bigInteger1", numberFormat = "0.#############E0", locale = "ru" ) + + } ) + Target sourceToTargetWithCustomLocale(Source source); + + @InheritInverseConfiguration( name = "sourceToTarget" ) Source targetToSource(Target target); + @InheritInverseConfiguration( name = "sourceToTargetWithCustomLocale" ) + Source targetToSourceWithCustomLocale(Target target); + @IterableMapping( numberFormat = NUMBER_FORMAT ) List sourceToTarget(List source); - @InheritInverseConfiguration + @InheritInverseConfiguration( name = "sourceToTarget" ) List targetToSource(List source); + @IterableMapping( numberFormat = "#0.#E0", locale = "fr" ) + List sourceToTargetWithCustomLocale(List source); + + @InheritInverseConfiguration( name = "sourceToTargetWithCustomLocale" ) + List targetToSourceWithCustomLocale(List source); + @MapMapping( keyNumberFormat = NUMBER_FORMAT, valueNumberFormat = "##" ) Map sourceToTarget(Map source); - @InheritInverseConfiguration + @MapMapping( keyNumberFormat = "#0.#E0", valueNumberFormat = "0.#############E0", locale = "fr" ) + Map sourceToTargetWithCustomLocale(Map source); + + @InheritInverseConfiguration( name = "sourceToTarget" ) Map targetToSource(Map source); + @InheritInverseConfiguration( name = "sourceToTargetWithCustomLocale" ) + Map targetToSourceWithCustomLocale(Map source); + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Target.java index 876b2bf8e6..948dcb15b7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/numbers/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.numbers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java index 36261ed1d3..42c72e0727 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/ConversionTest.java @@ -1,35 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.precedence; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Source.class, Target.class, SourceTargetMapper.class, IntegerStringMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ConversionTest { - @Test + @ProcessorTest public void shouldInvokeMappingMethodInsteadOfConversion() { Source source = new Source(); source.setFoo( 42 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java index af368b487a..b56498ef0d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/IntegerStringMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.precedence; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java index b6590a300a..85cc46cb5f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.precedence; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/SourceTargetMapper.java index fec8f56dd4..e618c13154 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.precedence; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.java index 8baa2f17d9..33d3ef2044 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/precedence/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.precedence; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Source.java index 0306c5a2ba..7f95abc797 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.string; @@ -36,6 +23,7 @@ public class Source { private Boolean boolBool; private char c; private Character cc; + private StringBuilder sb; private Object object; public byte getB() { @@ -173,4 +161,12 @@ public Object getObject() { public void setObject(Object object) { this.object = object; } + + public StringBuilder getSb() { + return sb; + } + + public void setSb(StringBuilder sb) { + this.sb = sb; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/SourceTargetMapper.java index e68a1be212..770c702f69 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.string; diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/StringConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/StringConversionTest.java index 8d621e6c7d..37d3c77b04 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/StringConversionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/StringConversionTest.java @@ -1,29 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.string; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; @@ -33,16 +18,15 @@ Target.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class StringConversionTest { private static final String STRING_CONSTANT = "String constant"; - @Rule - public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( SourceTargetMapper.class ); - @Test + @ProcessorTest public void shouldApplyStringConversions() { Source source = new Source(); source.setB( (byte) 1 ); @@ -61,6 +45,7 @@ public void shouldApplyStringConversions() { source.setBoolBool( Boolean.TRUE ); source.setC( 'G' ); source.setCc( 'H' ); + source.setSb( new StringBuilder( "SB" ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -81,9 +66,37 @@ public void shouldApplyStringConversions() { assertThat( target.getBoolBool() ).isEqualTo( "true" ); assertThat( target.getC() ).isEqualTo( "G" ); assertThat( target.getCc() ).isEqualTo( "H" ); + assertThat( target.getSb() ).isEqualTo( "SB" ); + } + + @IssueKey("2846") + @ProcessorTest + public void shouldNotApplyStringConversionsWhenNull() { + Source source = new Source(); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getB() ).isEqualTo( "0" ); + assertThat( target.getBb() ).isNull(); + assertThat( target.getS() ).isEqualTo( "0" ); + assertThat( target.getSs() ).isNull(); + assertThat( target.getI() ).isEqualTo( "0" ); + assertThat( target.getIi() ).isNull(); + assertThat( target.getL() ).isEqualTo( "0" ); + assertThat( target.getLl() ).isNull(); + assertThat( target.getF() ).isEqualTo( "0.0" ); + assertThat( target.getFf() ).isNull(); + assertThat( target.getD() ).isEqualTo( "0.0" ); + assertThat( target.getDd() ).isNull(); + assertThat( target.getBool() ).isEqualTo( "false" ); + assertThat( target.getBoolBool() ).isNull(); + assertThat( target.getC() ).isEqualTo( String.valueOf( '\u0000' ) ); + assertThat( target.getCc() ).isNull(); + assertThat( target.getSb() ).isNull(); } - @Test + @ProcessorTest public void shouldApplyReverseStringConversions() { Target target = new Target(); target.setB( "1" ); @@ -102,6 +115,7 @@ public void shouldApplyReverseStringConversions() { target.setBoolBool( "true" ); target.setC( "G" ); target.setCc( "H" ); + target.setSb( "SB" ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -122,9 +136,10 @@ public void shouldApplyReverseStringConversions() { assertThat( source.getBoolBool() ).isEqualTo( true ); assertThat( source.getC() ).isEqualTo( 'G' ); assertThat( source.getCc() ).isEqualTo( 'H' ); + assertThat( source.getSb().toString() ).isEqualTo( "SB" ); } - @Test + @ProcessorTest @IssueKey( "328" ) public void stringShouldBeMappedToObjectByReference() { Target target = new Target(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Target.java index 75b56deccc..7d58e9c12b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/string/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.conversion.string; @@ -36,6 +23,7 @@ public class Target { private String boolBool; private String c; private String cc; + private String sb; private String object; public String getB() { @@ -173,4 +161,12 @@ public String getObject() { public void setObject(String object) { this.object = object; } + + public String getSb() { + return sb; + } + + public void setSb(String sb) { + this.sb = sb; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URIConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URIConversionTest.java new file mode 100644 index 0000000000..d7d3ef4142 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URIConversionTest.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uri; + +import java.net.URI; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests conversions between {@link java.net.URI} and String. + * + * @author Maciej Kucharczyk + */ +@IssueKey("4018") +@WithClasses({ URISource.class, URITarget.class, URIMapper.class }) +public class URIConversionTest { + + @ProcessorTest + public void shouldApplyURIConversion() { + URISource source = new URISource(); + source.setUriA( URI.create( "https://mapstruct.org/" ) ); + + URITarget target = URIMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getUriA() ).isEqualTo( source.getUriA().toString() ); + } + + @ProcessorTest + public void shouldApplyReverseURIConversion() { + URITarget target = new URITarget(); + target.setUriA( "https://mapstruct.org/" ); + + URISource source = URIMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getUriA() ).isEqualTo( URI.create( target.getUriA() ) ); + } + + @ProcessorTest + public void shouldHandleInvalidURIString() { + URITarget target = new URITarget(); + target.setInvalidURI( "ht!tp://example.com" ); + + assertThatThrownBy( () -> URIMapper.INSTANCE.targetToSource( target ) ) + .isInstanceOf( IllegalArgumentException.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URIMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URIMapper.java new file mode 100644 index 0000000000..cac94a4efa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URIMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uri; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface URIMapper { + + URIMapper INSTANCE = Mappers.getMapper( URIMapper.class ); + + URITarget sourceToTarget(URISource source); + + URISource targetToSource(URITarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URISource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URISource.java new file mode 100644 index 0000000000..502169fccb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URISource.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uri; + +import java.net.URI; + +/** + * @author Maciej Kucharczyk + */ +public class URISource { + private URI uriA; + + private URI invalidURI; + + public URI getUriA() { + return uriA; + } + + public void setUriA(URI uriA) { + this.uriA = uriA; + } + + public URI getInvalidURI() { + return invalidURI; + } + + public void setInvalidURI(URI invalidURI) { + this.invalidURI = invalidURI; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URITarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URITarget.java new file mode 100644 index 0000000000..b221392127 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uri/URITarget.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uri; + +/** + * @author Maciej Kucharczyk + */ +public class URITarget { + private String uriA; + private String invalidURI; + + public String getUriA() { + return uriA; + } + + public void setUriA(String uriA) { + this.uriA = uriA; + } + + public String getInvalidURI() { + return invalidURI; + } + + public void setInvalidURI(String invalidURI) { + this.invalidURI = invalidURI; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/url/Source.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/Source.java new file mode 100644 index 0000000000..ece0501a08 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/Source.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.url; + +import java.net.URL; + +/** + * @author Adam Szatyin + */ +public class Source { + private URL url; + + private URL invalidURL; + + public URL getURL() { + return url; + } + + public void setURL(URL url) { + this.url = url; + } + + public URL getInvalidURL() { + return invalidURL; + } + + public void setInvalidURL(URL invalidURL) { + this.invalidURL = invalidURL; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/url/Target.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/Target.java new file mode 100644 index 0000000000..060f5582e1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/Target.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.url; + +/** + * @author Adam Szatyin + */ +public class Target { + private String url; + private String invalidURL; + + public String getURL() { + return this.url; + } + + public void setURL(final String url) { + this.url = url; + } + + public String getInvalidURL() { + return this.invalidURL; + } + + public void setInvalidURL(final String invalidURL) { + this.invalidURL = invalidURL; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/url/URLConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/URLConversionTest.java new file mode 100644 index 0000000000..f5a3b7f7e8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/URLConversionTest.java @@ -0,0 +1,76 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.url; + +import java.net.MalformedURLException; +import java.net.URI; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests conversions between {@link java.net.URL} and String. + * + * @author Adam Szatyin + */ +@WithClasses({ Source.class, Target.class, URLMapper.class }) +public class URLConversionTest { + + @ProcessorTest + public void shouldApplyURLConversion() throws MalformedURLException { + Source source = new Source(); + source.setURL( URI.create( "https://mapstruct.org/" ).toURL() ); + + Target target = URLMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getURL() ).isEqualTo( source.getURL().toString() ); + } + + @ProcessorTest + public void shouldApplyReverseURLConversion() throws MalformedURLException { + Target target = new Target(); + target.setURL( "https://mapstruct.org/" ); + + Source source = URLMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getURL() ).isEqualTo( URI.create( target.getURL() ).toURL() ); + } + + @ProcessorTest + public void shouldHandleInvalidURLString() { + Target target = new Target(); + target.setInvalidURL( "xxxxxx://mapstruct.org/" ); + + assertThatThrownBy( () -> URLMapper.INSTANCE.targetToSource( target ) ) + .isInstanceOf( RuntimeException.class ) + .getRootCause().isInstanceOf( MalformedURLException.class ); + } + + @ProcessorTest + public void shouldHandleInvalidURLStringWithMalformedURLException() { + Target target = new Target(); + target.setInvalidURL( "xxxxxx://mapstruct.org/" ); + + assertThatThrownBy( () -> URLMapper.INSTANCE.targetToSourceWithMalformedURLException( target ) ) + .isInstanceOf( MalformedURLException.class ); + } + + @ProcessorTest + public void shouldHandleNullURLString() { + Source source = new Source(); + + Target target = URLMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getURL() ).isNull(); + assertThat( target.getInvalidURL() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/url/URLMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/URLMapper.java new file mode 100644 index 0000000000..e93c47726c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/url/URLMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.url; + +import java.net.MalformedURLException; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface URLMapper { + + URLMapper INSTANCE = Mappers.getMapper( URLMapper.class ); + + Target sourceToTarget(Source source); + + Source targetToSource(Target target); + + Source targetToSourceWithMalformedURLException(Target target) throws MalformedURLException; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDConversionTest.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDConversionTest.java new file mode 100644 index 0000000000..51eab29cda --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDConversionTest.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uuid; + +import java.util.UUID; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * Tests conversions between {@link java.util.UUID} and String. + * + * @author Jason Bodnar + */ +@IssueKey("2391") +@WithClasses({ UUIDSource.class, UUIDTarget.class, UUIDMapper.class }) +public class UUIDConversionTest { + + @ProcessorTest + public void shouldApplyUUIDConversion() { + UUIDSource source = new UUIDSource(); + source.setUUIDA( UUID.randomUUID() ); + + UUIDTarget target = UUIDMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getUUIDA() ).isEqualTo( source.getUUIDA().toString() ); + } + + @ProcessorTest + public void shouldApplyReverseUUIDConversion() { + UUIDTarget target = new UUIDTarget(); + target.setUUIDA( UUID.randomUUID().toString() ); + + UUIDSource source = UUIDMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getUUIDA() ).isEqualTo( UUID.fromString( target.getUUIDA() ) ); + } + + @ProcessorTest + public void shouldHandleInvalidUUIDString() { + UUIDTarget target = new UUIDTarget(); + target.setInvalidUUID( "XXXXXXXXX" ); + + assertThatThrownBy( () -> UUIDMapper.INSTANCE.targetToSource( target ) ) + .isInstanceOf( IllegalArgumentException.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDMapper.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDMapper.java new file mode 100644 index 0000000000..8430b0fdce --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uuid; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface UUIDMapper { + + UUIDMapper INSTANCE = Mappers.getMapper( UUIDMapper.class ); + + UUIDTarget sourceToTarget(UUIDSource source); + + UUIDSource targetToSource(UUIDTarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDSource.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDSource.java new file mode 100644 index 0000000000..220ce5a76a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDSource.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uuid; + +import java.util.UUID; + +/** + * @author Jason Bodnar + */ +public class UUIDSource { + private UUID uuidA; + + private UUID invalidUUID; + + public UUID getUUIDA() { + return this.uuidA; + } + + public void setUUIDA(final UUID uuidA) { + this.uuidA = uuidA; + } + + public UUID getInvalidUUID() { + return invalidUUID; + } + + public void setInvalidUUID(final UUID invalidUUID) { + this.invalidUUID = invalidUUID; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDTarget.java b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDTarget.java new file mode 100644 index 0000000000..4fd2558141 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/conversion/uuid/UUIDTarget.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.conversion.uuid; + +/** + * @author Jason Bodnar + */ +public class UUIDTarget { + private String uuidA; + private String invalidUUID; + + public String getUUIDA() { + return this.uuidA; + } + + public void setUUIDA(final String uuidA) { + this.uuidA = uuidA; + } + + public String getInvalidUUID() { + return this.invalidUUID; + } + + public void setInvalidUUID(final String invalidUUID) { + this.invalidUUID = invalidUUID; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/Address.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/Address.java index af01a27e5c..fe46600813 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/Address.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/AddressDto.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/AddressDto.java index 92f4d01e60..bc1c576582 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/AddressDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/AnnotatedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnnotatedMapper.java new file mode 100644 index 0000000000..6da0d70c93 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnnotatedMapper.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +@DecoratedWith(AnnotatedMapperDecorator.class) +public interface AnnotatedMapper { + + AnnotatedMapper INSTANCE = Mappers.getMapper( AnnotatedMapper.class ); + + Target toTarget(Source source); + + class Source { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Target { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/AnnotatedMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnnotatedMapperDecorator.java new file mode 100644 index 0000000000..6bf7a1fd66 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnnotatedMapperDecorator.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator; + +import org.mapstruct.AnnotateWith; + +@AnnotateWith(value = TestAnnotation.class, elements = @AnnotateWith.Element(strings = "decoratorValue")) +public abstract class AnnotatedMapperDecorator implements AnnotatedMapper { + + private final AnnotatedMapper delegate; + + public AnnotatedMapperDecorator(AnnotatedMapper delegate) { + this.delegate = delegate; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapper.java index 9a7d2c44b3..960250a0d5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapperDecorator.java index 45def49fa2..0967bcf70f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/AnotherPersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratedWithAnnotatedWithTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratedWithAnnotatedWithTest.java new file mode 100644 index 0000000000..1e3d574a6d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratedWithAnnotatedWithTest.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for the application of @AnnotatedWith on decorator classes. + */ +@IssueKey("3659") +@WithClasses({ + TestAnnotation.class, + AnnotatedMapper.class, + AnnotatedMapperDecorator.class +}) +public class DecoratedWithAnnotatedWithTest { + + @ProcessorTest + public void shouldApplyAnnotationFromDecorator() { + Class implementationClass = AnnotatedMapper.INSTANCE.getClass(); + + assertThat( implementationClass ).hasAnnotation( TestAnnotation.class ); + assertThat( implementationClass.getAnnotation( TestAnnotation.class ).value() ).isEqualTo( "decoratorValue" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratorTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratorTest.java index cf51db200c..4e70581983 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratorTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/DecoratorTest.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Calendar; - import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for the application of decorators. @@ -45,10 +29,9 @@ AddressDto.class }) @IssueKey("163") -@RunWith(AnnotationProcessorTestRunner.class) public class DecoratorTest { - @Test + @ProcessorTest @WithClasses({ PersonMapper.class, PersonMapperDecorator.class @@ -56,7 +39,7 @@ public class DecoratorTest { public void shouldInvokeDecoratorMethods() { //given Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); + birthday.set( 1928, Calendar.MAY, 23 ); Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); //when @@ -69,7 +52,7 @@ public void shouldInvokeDecoratorMethods() { assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); } - @Test + @ProcessorTest @WithClasses({ PersonMapper.class, PersonMapperDecorator.class @@ -86,7 +69,7 @@ public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() { assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); } - @Test + @ProcessorTest @WithClasses({ PersonMapper.class, PersonMapperDecorator.class @@ -104,7 +87,7 @@ public void shouldDelegateNonDecoratedVoidMethodsToDefaultImplementation() { assertThat( address.getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); } - @Test + @ProcessorTest @WithClasses({ AnotherPersonMapper.class, AnotherPersonMapperDecorator.class @@ -112,7 +95,7 @@ public void shouldDelegateNonDecoratedVoidMethodsToDefaultImplementation() { public void shouldApplyDecoratorWithDefaultConstructor() { //given Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); + birthday.set( 1928, Calendar.MAY, 23 ); Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); //when @@ -125,7 +108,7 @@ public void shouldApplyDecoratorWithDefaultConstructor() { assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); } - @Test + @ProcessorTest @WithClasses({ YetAnotherPersonMapper.class, YetAnotherPersonMapperDecorator.class @@ -133,7 +116,7 @@ public void shouldApplyDecoratorWithDefaultConstructor() { public void shouldApplyDelegateToClassBasedMapper() { //given Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); + birthday.set( 1928, Calendar.MAY, 23 ); Person person = new Person2( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); @@ -148,7 +131,7 @@ public void shouldApplyDelegateToClassBasedMapper() { } @IssueKey("173") - @Test + @ProcessorTest @WithClasses({ Person2Mapper.class, Person2MapperDecorator.class, @@ -163,7 +146,7 @@ public void shouldApplyDelegateToClassBasedMapper() { public void shouldApplyCustomMappers() { //given Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); + birthday.set( 1928, Calendar.MAY, 23 ); Person2 person = new Person2( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); person.setEmployer( new Employer( "ACME" ) ); person.setSportsClub( new SportsClub( "SC Duckburg" ) ); @@ -184,7 +167,7 @@ public void shouldApplyCustomMappers() { assertThat( personDto.getSportsClub().getName() ).isEqualTo( "SC Duckburg" ); } - @Test + @ProcessorTest @WithClasses({ ErroneousPersonMapper.class, ErroneousPersonMapperDecorator.class @@ -194,8 +177,8 @@ public void shouldApplyCustomMappers() { diagnostics = { @Diagnostic(type = ErroneousPersonMapper.class, kind = Kind.ERROR, - line = 27, - messageRegExp = "Specified decorator type is no subtype of the annotated mapper type") + line = 14, + message = "Specified decorator type is no subtype of the annotated mapper type.") } ) public void shouldRaiseErrorInCaseWrongDecoratorTypeIsGiven() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/Employer.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/Employer.java index a53dbd9b44..aef87b819e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/Employer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/Employer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerDto.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerDto.java index 99bfe1f03f..3dca441eca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerMapper.java index ea6368c7a0..697526d76c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/EmployerMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapper.java index 38756603e4..1019951b9f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapperDecorator.java index c82e3f6c09..54eb009527 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/ErroneousPersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person.java index b3dc9348dc..b9773e0043 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2.java index 56eb026fcf..d08694b118 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2Mapper.java index 4f9a06e8d3..544f5be4ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2MapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2MapperDecorator.java index bd4528a2bb..fa7cc12ac9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2MapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/Person2MapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto.java index 5f7a414532..4036686828 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto2.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto2.java index de9eacebb8..4b1438e2b9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonDto2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapper.java index ca809547d5..66ddbcd4f5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapperDecorator.java index 4d7a7ad54b..f3c3ca151f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/PersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClub.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClub.java index a437f46502..13b7259855 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClub.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClub.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClubDto.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClubDto.java index 43f441e7e9..818454f74e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClubDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/SportsClubDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/TestAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/TestAnnotation.java new file mode 100644 index 0000000000..742184d261 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/TestAnnotation.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Test annotation for testing @AnnotatedWith on decorators. + */ +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +public @interface TestAnnotation { + String value() default ""; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapper.java index a42c016b0b..fa41843773 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapperDecorator.java index e577c65d45..a22ce77827 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/YetAnotherPersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaAnnotateWithMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaAnnotateWithMapper.java new file mode 100644 index 0000000000..a1a754158b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaAnnotateWithMapper.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jakarta.annotatewith; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +/** + * A mapper using Jakarta component model with a decorator. + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA) +@DecoratedWith(JakartaAnnotateWithWithMapperDecorator.class) +public interface JakartaAnnotateWithMapper { + + /** + * Maps a person to a person DTO. + * + * @param person the person to map + * @return the person DTO + */ + @Mapping(target = "name", ignore = true) + PersonDto personToPersonDto(Person person); + + /** + * Maps an address to an address DTO. + * + * @param address the address to map + * @return the address DTO + */ + AddressDto addressToAddressDto(Address address); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaAnnotateWithWithMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaAnnotateWithWithMapperDecorator.java new file mode 100644 index 0000000000..89a42aaf6e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaAnnotateWithWithMapperDecorator.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jakarta.annotatewith; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.mapstruct.AnnotateWith; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.test.decorator.TestAnnotation; + +/** + * A decorator for {@link JakartaAnnotateWithMapper}. + */ +@AnnotateWith(value = TestAnnotation.class) +public abstract class JakartaAnnotateWithWithMapperDecorator implements JakartaAnnotateWithMapper { + + @Inject + @Named("org.mapstruct.ap.test.decorator.jakarta.annotatewith.JakartaAnnotateWithMapperImpl_") + private JakartaAnnotateWithMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + return dto; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaDecoratorAnnotateWithTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaDecoratorAnnotateWithTest.java new file mode 100644 index 0000000000..ac213d96a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/annotatewith/JakartaDecoratorAnnotateWithTest.java @@ -0,0 +1,105 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jakarta.annotatewith; + +import java.util.Calendar; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.test.decorator.TestAnnotation; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for the application of @AnnotateWith on decorator classes with Jakarta component model. + */ +@IssueKey("3659") +@WithClasses({ + Person.class, + PersonDto.class, + Address.class, + AddressDto.class, + JakartaAnnotateWithMapper.class, + TestAnnotation.class, + JakartaAnnotateWithWithMapperDecorator.class +}) +@ComponentScan(basePackageClasses = JakartaDecoratorAnnotateWithTest.class) +@Configuration +@WithJakartaInject +public class JakartaDecoratorAnnotateWithTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Inject + @Named + private JakartaAnnotateWithMapper jakartaAnnotateWithMapper; + + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldInvokeDecoratorMethods() { + Calendar birthday = Calendar.getInstance(); + birthday.set( 1928, Calendar.MAY, 23 ); + Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); + + PersonDto personDto = jakartaAnnotateWithMapper.personToPersonDto( person ); + + assertThat( personDto ).isNotNull(); + assertThat( personDto.getName() ).isEqualTo( "Gary Crant" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } + + @ProcessorTest + public void hasCorrectImports() { + // check the decorator + generatedSource.forMapper( JakartaAnnotateWithMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@TestAnnotation" ) + .contains( "@Singleton" + lineSeparator() + "@Named" ) + .doesNotContain( "javax.inject" ); + // check the plain mapper + generatedSource.forDecoratedMapper( JakartaAnnotateWithMapper.class ).content() + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Singleton" + lineSeparator() + "@Named" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/JakartaJsr330DecoratorTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/JakartaJsr330DecoratorTest.java new file mode 100644 index 0000000000..1d285af365 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/JakartaJsr330DecoratorTest.java @@ -0,0 +1,108 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jakarta.jsr330; + +import java.util.Calendar; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + Person.class, + PersonDto.class, + Address.class, + AddressDto.class, + PersonMapper.class, + PersonMapperDecorator.class +}) +@IssueKey("2567") +@ComponentScan(basePackageClasses = JakartaJsr330DecoratorTest.class) +@Configuration +@WithJakartaInject +public class JakartaJsr330DecoratorTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Inject + @Named + private PersonMapper personMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldInvokeDecoratorMethods() { + Calendar birthday = Calendar.getInstance(); + birthday.set( 1928, Calendar.MAY, 23 ); + Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); + + PersonDto personDto = personMapper.personToPersonDto( person ); + + assertThat( personDto ).isNotNull(); + assertThat( personDto.getName() ).isEqualTo( "Gary Crant" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } + + @ProcessorTest + public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() { + Address address = new Address( "42 Ocean View Drive" ); + + AddressDto addressDto = personMapper.addressToAddressDto( address ); + + assertThat( addressDto ).isNotNull(); + assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } + + @ProcessorTest + public void hasCorrectImports() { + // check the decorator + generatedSource.forMapper( PersonMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Singleton" + lineSeparator() + "@Named" ) + .doesNotContain( "javax.inject" ); + // check the plain mapper + generatedSource.forDecoratedMapper( PersonMapper.class ).content() + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Singleton" + lineSeparator() + "@Named" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/PersonMapper.java new file mode 100644 index 0000000000..74ef38439f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/PersonMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jakarta.jsr330; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) +@DecoratedWith(PersonMapperDecorator.class) +public interface PersonMapper { + + @Mapping( target = "name", ignore = true ) + PersonDto personToPersonDto(Person person); + + AddressDto addressToAddressDto(Address address); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/PersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/PersonMapperDecorator.java new file mode 100644 index 0000000000..7642dc5d52 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jakarta/jsr330/PersonMapperDecorator.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jakarta.jsr330; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +public abstract class PersonMapperDecorator implements PersonMapper { + + @Inject + @Named("org.mapstruct.ap.test.decorator.jakarta.jsr330.PersonMapperImpl_") + private PersonMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + + return dto; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/Jsr330DecoratorTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/Jsr330DecoratorTest.java index 4089b05743..008f8cfe12 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/Jsr330DecoratorTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/Jsr330DecoratorTest.java @@ -1,48 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.jsr330; -import static java.lang.System.lineSeparator; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Calendar; - -import javax.inject.Inject; -import javax.inject.Named; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.decorator.Address; import org.mapstruct.ap.test.decorator.AddressDto; import org.mapstruct.ap.test.decorator.Person; import org.mapstruct.ap.test.decorator.PersonDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxInject; import org.mapstruct.ap.testutil.runner.GeneratedSource; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; /** * Test for the application of decorators using component model jsr330. @@ -58,62 +32,14 @@ PersonMapperDecorator.class }) @IssueKey("592") -@RunWith(AnnotationProcessorTestRunner.class) -@ComponentScan(basePackageClasses = Jsr330DecoratorTest.class) -@Configuration +@WithJavaxInject public class Jsr330DecoratorTest { - private final GeneratedSource generatedSource = new GeneratedSource(); - - @Inject - @Named - private PersonMapper personMapper; - private ConfigurableApplicationContext context; - - @Rule - public GeneratedSource getGeneratedSource() { - return generatedSource; - } - - @Before - public void springUp() { - context = new AnnotationConfigApplicationContext( getClass() ); - context.getAutowireCapableBeanFactory().autowireBean( this ); - } - - @After - public void springDown() { - if ( context != null ) { - context.close(); - } - } - - @Test - public void shouldInvokeDecoratorMethods() { - Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); - Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); - - PersonDto personDto = personMapper.personToPersonDto( person ); - - assertThat( personDto ).isNotNull(); - assertThat( personDto.getName() ).isEqualTo( "Gary Crant" ); - assertThat( personDto.getAddress() ).isNotNull(); - assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); - } - - @Test - public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() { - Address address = new Address( "42 Ocean View Drive" ); - - AddressDto addressDto = personMapper.addressToAddressDto( address ); - - assertThat( addressDto ).isNotNull(); - assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); @IssueKey("664") - @Test + @ProcessorTest public void hasSingletonAnnotation() { // check the decorator generatedSource.forMapper( PersonMapper.class ).content() diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapper.java index 9a2e90ae89..770393f817 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapper.java @@ -1,32 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.jsr330; import org.mapstruct.DecoratedWith; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.decorator.Address; import org.mapstruct.ap.test.decorator.AddressDto; import org.mapstruct.ap.test.decorator.Person; import org.mapstruct.ap.test.decorator.PersonDto; -@Mapper(componentModel = "jsr330") +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) @DecoratedWith(PersonMapperDecorator.class) public interface PersonMapper { diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapperDecorator.java index cb557348d9..98d39cc0c8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/PersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.jsr330; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330AnnotateWithMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330AnnotateWithMapper.java new file mode 100644 index 0000000000..7e6ab8b7bd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330AnnotateWithMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jsr330.annotatewith; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +/** + * A mapper using JSR-330 component model with a decorator. + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) +@DecoratedWith(Jsr330AnnotateWithMapperDecorator.class) +public interface Jsr330AnnotateWithMapper { + + @Mapping(target = "name", ignore = true) + PersonDto personToPersonDto(Person person); + + AddressDto addressToAddressDto(Address address); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330AnnotateWithMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330AnnotateWithMapperDecorator.java new file mode 100644 index 0000000000..96cee9f824 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330AnnotateWithMapperDecorator.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jsr330.annotatewith; + +import javax.inject.Inject; +import javax.inject.Named; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.test.decorator.TestAnnotation; + +/** + * A decorator for {@link Jsr330AnnotateWithMapper}. + */ +@AnnotateWith(value = TestAnnotation.class) +public abstract class Jsr330AnnotateWithMapperDecorator implements Jsr330AnnotateWithMapper { + + @Inject + @Named("org.mapstruct.ap.test.decorator.jsr330.annotatewith.Jsr330AnnotateWithMapperImpl_") + private Jsr330AnnotateWithMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + return dto; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330DecoratorAnnotateWithTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330DecoratorAnnotateWithTest.java new file mode 100644 index 0000000000..6cb6384f85 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/jsr330/annotatewith/Jsr330DecoratorAnnotateWithTest.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.jsr330.annotatewith; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.test.decorator.TestAnnotation; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * Test for the application of @AnnotateWith on decorator classes with JSR-330 component model. + */ +@IssueKey("3659") +@WithClasses({ + Person.class, + PersonDto.class, + Address.class, + AddressDto.class, + Jsr330AnnotateWithMapper.class, + Jsr330AnnotateWithMapperDecorator.class, + TestAnnotation.class +}) +@WithJavaxInject +public class Jsr330DecoratorAnnotateWithTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldContainCustomAnnotation() { + generatedSource.forMapper( Jsr330AnnotateWithMapper.class ) + .content() + .contains( "@TestAnnotation" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/AnnotateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/AnnotateMapper.java new file mode 100644 index 0000000000..0ba8e88299 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/AnnotateMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +@DecoratedWith(AnnotateMapperDecorator.class) +public interface AnnotateMapper { + + @Mapping(target = "name", ignore = true) + PersonDto personToPersonDto(Person person); + + AddressDto addressToAddressDto(Address address); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/AnnotateMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/AnnotateMapperDecorator.java new file mode 100644 index 0000000000..cff0a4c148 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/AnnotateMapperDecorator.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Primary; +import org.springframework.stereotype.Component; + +@AnnotateWith(value = Component.class, elements = @AnnotateWith.Element(strings = "decoratorComponent")) +@AnnotateWith(value = Primary.class) +public abstract class AnnotateMapperDecorator implements AnnotateMapper { + + @Autowired + @Qualifier("delegate") + private AnnotateMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + return dto; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomAnnotateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomAnnotateMapper.java new file mode 100644 index 0000000000..9e2e35676c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomAnnotateMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +@DecoratedWith(CustomAnnotateMapperDecorator.class) +public interface CustomAnnotateMapper { + + @Mapping(target = "name", ignore = true) + PersonDto personToPersonDto(Person person); + + AddressDto addressToAddressDto(Address address); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomAnnotateMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomAnnotateMapperDecorator.java new file mode 100644 index 0000000000..3668d98b04 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomAnnotateMapperDecorator.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +@AnnotateWith(value = CustomComponent.class, elements = @AnnotateWith.Element(strings = "customComponentDecorator")) +@AnnotateWith(value = CustomPrimary.class) +public abstract class CustomAnnotateMapperDecorator implements CustomAnnotateMapper { + + @Autowired + @Qualifier("delegate") + private CustomAnnotateMapper delegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = delegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + return dto; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomComponent.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomComponent.java new file mode 100644 index 0000000000..be71249f2a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomComponent.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.stereotype.Component; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Component +public @interface CustomComponent { + String value() default ""; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomPrimary.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomPrimary.java new file mode 100644 index 0000000000..4e18bdbc7d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/CustomPrimary.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.context.annotation.Primary; + +@Target(ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@Primary +public @interface CustomPrimary { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/SpringDecoratorAnnotateWithTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/SpringDecoratorAnnotateWithTest.java new file mode 100644 index 0000000000..7b3911c22b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/annotatewith/SpringDecoratorAnnotateWithTest.java @@ -0,0 +1,118 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.annotatewith; + +import java.util.Calendar; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for the application of @AnnotateWith on decorator classes with Spring component model. + */ +@IssueKey("3659") +@WithClasses({ + Person.class, + PersonDto.class, + Address.class, + AddressDto.class, + AnnotateMapper.class, + AnnotateMapperDecorator.class, + CustomComponent.class, + CustomPrimary.class, + CustomAnnotateMapper.class, + CustomAnnotateMapperDecorator.class +}) +@WithSpring +@ComponentScan(basePackageClasses = SpringDecoratorAnnotateWithTest.class) +@Configuration +public class SpringDecoratorAnnotateWithTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Autowired + private AnnotateMapper annotateMapper; + + @Autowired + private CustomAnnotateMapper customAnnotateMapper; + + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldNotDuplicateComponentAnnotation() { + generatedSource.forMapper( AnnotateMapper.class ) + .content() + .contains( "@Component(value = \"decoratorComponent\")", "@Primary" ) + .doesNotContain( "@Component" + System.lineSeparator() ); + } + + @ProcessorTest + public void shouldNotDuplicateCustomComponentAnnotation() { + generatedSource.forMapper( CustomAnnotateMapper.class ) + .content() + .contains( "@CustomComponent(value = \"customComponentDecorator\")", "@CustomPrimary" ) + .doesNotContain( "@Component" ); + } + + @ProcessorTest + public void shouldInvokeAnnotateDecoratorMethods() { + Calendar birthday = Calendar.getInstance(); + birthday.set( 1928, Calendar.MAY, 23 ); + Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); + + PersonDto personDto = annotateMapper.personToPersonDto( person ); + + assertThat( personDto ).isNotNull(); + assertThat( personDto.getName() ).isEqualTo( "Gary Crant" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } + + @ProcessorTest + public void shouldInvokeCustomAnnotateDecoratorMethods() { + Calendar birthday = Calendar.getInstance(); + birthday.set( 1928, Calendar.MAY, 23 ); + Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); + + PersonDto personDto = customAnnotateMapper.personToPersonDto( person ); + + assertThat( personDto ).isNotNull(); + assertThat( personDto.getName() ).isEqualTo( "Gary Crant" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapper.java index 7dd675c9bd..4ada1124c0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.spring.constructor; @@ -22,12 +9,13 @@ import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.decorator.Address; import org.mapstruct.ap.test.decorator.AddressDto; import org.mapstruct.ap.test.decorator.Person; import org.mapstruct.ap.test.decorator.PersonDto; -@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR) +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.CONSTRUCTOR) @DecoratedWith(PersonMapperDecorator.class) public interface PersonMapper { diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapperDecorator.java index 0f7c0e726e..6c406e334d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/PersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.spring.constructor; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/SpringDecoratorTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/SpringDecoratorTest.java index dd3aefcfbf..6d18555372 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/SpringDecoratorTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/constructor/SpringDecoratorTest.java @@ -1,44 +1,30 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.spring.constructor; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Calendar; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.mapstruct.ap.test.decorator.Address; import org.mapstruct.ap.test.decorator.AddressDto; import org.mapstruct.ap.test.decorator.Person; import org.mapstruct.ap.test.decorator.PersonDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithSpring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for the application of decorators using component model spring. * @@ -53,33 +39,33 @@ PersonMapperDecorator.class }) @IssueKey("592") -@RunWith(AnnotationProcessorTestRunner.class) @ComponentScan(basePackageClasses = SpringDecoratorTest.class) @Configuration +@WithSpring public class SpringDecoratorTest { @Autowired private PersonMapper personMapper; private ConfigurableApplicationContext context; - @Before + @BeforeEach public void springUp() { context = new AnnotationConfigApplicationContext( getClass() ); context.getAutowireCapableBeanFactory().autowireBean( this ); } - @After + @AfterEach public void springDown() { if ( context != null ) { context.close(); } } - @Test + @ProcessorTest public void shouldInvokeDecoratorMethods() { //given Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); + birthday.set( 1928, Calendar.MAY, 23 ); Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); //when @@ -92,7 +78,7 @@ public void shouldInvokeDecoratorMethods() { assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); } - @Test + @ProcessorTest public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() { //given Address address = new Address( "42 Ocean View Drive" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapper.java index 3fdbd0dd6e..5cbe867e7a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.spring.field; @@ -22,12 +9,13 @@ import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.decorator.Address; import org.mapstruct.ap.test.decorator.AddressDto; import org.mapstruct.ap.test.decorator.Person; import org.mapstruct.ap.test.decorator.PersonDto; -@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.FIELD) +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.FIELD) @DecoratedWith(PersonMapperDecorator.class) public interface PersonMapper { diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapperDecorator.java index c9069cf9e1..315e1d0f26 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/PersonMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.spring.field; diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/SpringDecoratorTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/SpringDecoratorTest.java index e95fa9a6f9..ac0af86381 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/SpringDecoratorTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/field/SpringDecoratorTest.java @@ -1,44 +1,30 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.decorator.spring.field; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Calendar; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.mapstruct.ap.test.decorator.Address; import org.mapstruct.ap.test.decorator.AddressDto; import org.mapstruct.ap.test.decorator.Person; import org.mapstruct.ap.test.decorator.PersonDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithSpring; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for the application of decorators using component model spring. * @@ -52,8 +38,8 @@ PersonMapper.class, PersonMapperDecorator.class }) +@WithSpring @IssueKey("592") -@RunWith(AnnotationProcessorTestRunner.class) @ComponentScan(basePackageClasses = SpringDecoratorTest.class) @Configuration public class SpringDecoratorTest { @@ -62,24 +48,24 @@ public class SpringDecoratorTest { private PersonMapper personMapper; private ConfigurableApplicationContext context; - @Before + @BeforeEach public void springUp() { context = new AnnotationConfigApplicationContext( getClass() ); context.getAutowireCapableBeanFactory().autowireBean( this ); } - @After + @AfterEach public void springDown() { if ( context != null ) { context.close(); } } - @Test + @ProcessorTest public void shouldInvokeDecoratorMethods() { //given Calendar birthday = Calendar.getInstance(); - birthday.set( 1928, 4, 23 ); + birthday.set( 1928, Calendar.MAY, 23 ); Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); //when @@ -92,7 +78,7 @@ public void shouldInvokeDecoratorMethods() { assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); } - @Test + @ProcessorTest public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() { //given Address address = new Address( "42 Ocean View Drive" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/PersonMapper.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/PersonMapper.java new file mode 100644 index 0000000000..20ac9d874c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/PersonMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.setter; + +import org.mapstruct.DecoratedWith; +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; + +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.SETTER) +@DecoratedWith(PersonMapperDecorator.class) +public interface PersonMapper { + + @Mapping( target = "name", ignore = true ) + PersonDto personToPersonDto(Person person); + + AddressDto addressToAddressDto(Address address); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/PersonMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/PersonMapperDecorator.java new file mode 100644 index 0000000000..8f306284a1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/PersonMapperDecorator.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.setter; + +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; + +public abstract class PersonMapperDecorator implements PersonMapper { + + private PersonMapper decoratorDelegate; + + @Override + public PersonDto personToPersonDto(Person person) { + PersonDto dto = decoratorDelegate.personToPersonDto( person ); + dto.setName( person.getFirstName() + " " + person.getLastName() ); + + return dto; + } + + @Autowired + public void setDecoratorDelegate(@Qualifier("delegate") PersonMapper decoratorDelegate) { + this.decoratorDelegate = decoratorDelegate; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/SpringDecoratorTest.java b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/SpringDecoratorTest.java new file mode 100644 index 0000000000..c03b05395a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/decorator/spring/setter/SpringDecoratorTest.java @@ -0,0 +1,88 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.decorator.spring.setter; + +import java.util.Calendar; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.mapstruct.ap.test.decorator.Address; +import org.mapstruct.ap.test.decorator.AddressDto; +import org.mapstruct.ap.test.decorator.Person; +import org.mapstruct.ap.test.decorator.PersonDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + Person.class, + PersonDto.class, + Address.class, + AddressDto.class, + PersonMapper.class, + PersonMapperDecorator.class +}) +@WithSpring +@IssueKey("3229") +@ComponentScan(basePackageClasses = SpringDecoratorTest.class) +@Configuration +public class SpringDecoratorTest { + + @Autowired + private PersonMapper personMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldInvokeDecoratorMethods() { + //given + Calendar birthday = Calendar.getInstance(); + birthday.set( 1928, Calendar.MAY, 23 ); + Person person = new Person( "Gary", "Crant", birthday.getTime(), new Address( "42 Ocean View Drive" ) ); + + //when + PersonDto personDto = personMapper.personToPersonDto( person ); + + //then + assertThat( personDto ).isNotNull(); + assertThat( personDto.getName() ).isEqualTo( "Gary Crant" ); + assertThat( personDto.getAddress() ).isNotNull(); + assertThat( personDto.getAddress().getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } + + @ProcessorTest + public void shouldDelegateNonDecoratedMethodsToDefaultImplementation() { + //given + Address address = new Address( "42 Ocean View Drive" ); + + //when + AddressDto addressDto = personMapper.addressToAddressDto( address ); + + //then + assertThat( addressDto ).isNotNull(); + assertThat( addressDto.getAddressLine() ).isEqualTo( "42 Ocean View Drive" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/DefaultComponentModelMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/DefaultComponentModelMapperTest.java new file mode 100644 index 0000000000..2c860f05f7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/DefaultComponentModelMapperTest.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2277") +@WithClasses({ + Source.class, + Target.class, +}) +public class DefaultComponentModelMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + InstanceIterableMapper.class, + InstanceMapper.class, + NonInstanceIterableMapper.class, + NonInstanceMapper.class, + NonPublicIterableMapper.class, + NonPublicMapper.class, + }) + public void shouldGenerateCorrectMapperInstantiation() { + generatedSource.addComparisonToFixtureFor( + InstanceIterableMapper.class, + NonInstanceIterableMapper.class, + NonPublicIterableMapper.class + ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/InstanceIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/InstanceIterableMapper.java new file mode 100644 index 0000000000..b5b0506b62 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/InstanceIterableMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import java.util.List; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = InstanceMapper.class) +public interface InstanceIterableMapper { + + List map(List list); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/InstanceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/InstanceMapper.java new file mode 100644 index 0000000000..902ed551cd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/InstanceMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface InstanceMapper { + + InstanceMapper INSTANCE = Mappers.getMapper( InstanceMapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonInstanceIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonInstanceIterableMapper.java new file mode 100644 index 0000000000..6cdbe53006 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonInstanceIterableMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import java.util.List; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = NonInstanceMapper.class) +public interface NonInstanceIterableMapper { + + List map(List list); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonInstanceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonInstanceMapper.java new file mode 100644 index 0000000000..0d7f68392c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonInstanceMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface NonInstanceMapper { + + NonInstanceMapper MAPPER = Mappers.getMapper( NonInstanceMapper.class ); + + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonPublicIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonPublicIterableMapper.java new file mode 100644 index 0000000000..20d6dbc1e7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonPublicIterableMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import java.util.List; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(uses = NonPublicMapper.class) +public interface NonPublicIterableMapper { + + List map(List list); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonPublicMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonPublicMapper.java new file mode 100644 index 0000000000..36f9b978f2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/NonPublicMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public abstract class NonPublicMapper { + + static final NonPublicMapper INSTANCE = Mappers.getMapper( NonPublicMapper.class ); + + public abstract Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/Source.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/Source.java new file mode 100644 index 0000000000..a6aa152e20 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/Source.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private final String id; + + public Source(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/Target.java b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/Target.java new file mode 100644 index 0000000000..da7bfdbed0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultcomponentmodel/Target.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultcomponentmodel; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final String id; + + public Target(String id) { + this.id = id; + } + + public String getId() { + return id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryDts.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryDts.java index 11c5810496..8caa4bd27a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryDts.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryDts.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryEntity.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryEntity.java index ec09a9fbbe..e11810aa78 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapper.java index 3f3b9ba7bf..820e05b2c6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapperMultipleSources.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapperMultipleSources.java new file mode 100644 index 0000000000..11a424d929 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/CountryMapperMultipleSources.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultvalue; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CountryMapperMultipleSources { + + CountryMapperMultipleSources INSTANCE = Mappers.getMapper( CountryMapperMultipleSources.class ); + + @Mapping(target = "code", defaultValue = "CH") + @Mapping(target = "region", source = "regionCode") + CountryDts map(CountryEntity entity, String regionCode); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/DefaultValueTest.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/DefaultValueTest.java index f1b8e0e23e..114d762c03 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/DefaultValueTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/DefaultValueTest.java @@ -1,50 +1,32 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; -import static org.assertj.core.api.Assertions.assertThat; - -import java.text.ParseException; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.defaultvalue.other.Continent; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; - -@IssueKey( "600" ) -@RunWith( AnnotationProcessorTestRunner.class ) -@WithClasses( { - CountryEntity.class, - CountryDts.class, - Continent.class -} ) + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("600") +@WithClasses({ + CountryEntity.class, + CountryDts.class, + Continent.class +}) public class DefaultValueTest { - @Test - @WithClasses( { - Region.class, - CountryMapper.class - } ) + @ProcessorTest + @WithClasses({ + Region.class, + CountryMapper.class + }) /** * Checks: *
        @@ -70,11 +52,11 @@ public void shouldDefaultValueAndUseConstantExpression() { assertThat( countryDts.getContinent() ).isEqualTo( Continent.EUROPE ); } - @Test - @WithClasses( { - Region.class, - CountryMapper.class - } ) + @ProcessorTest + @WithClasses({ + Region.class, + CountryMapper.class + }) public void shouldIgnoreDefaultValue() { CountryEntity countryEntity = new CountryEntity(); countryEntity.setCode( "US" ); @@ -91,11 +73,11 @@ public void shouldIgnoreDefaultValue() { assertThat( countryDts.getContinent() ).isEqualTo( Continent.NORTH_AMERICA ); } - @Test - @WithClasses( { - Region.class, - CountryMapper.class - } ) + @ProcessorTest + @WithClasses({ + Region.class, + CountryMapper.class + }) public void shouldHandleUpdateMethodsFromDtsToEntity() { CountryEntity countryEntity = new CountryEntity(); CountryDts countryDts = new CountryDts(); @@ -109,11 +91,11 @@ public void shouldHandleUpdateMethodsFromDtsToEntity() { assertThat( countryEntity.getContinent() ).isEqualTo( Continent.EUROPE ); } - @Test - @WithClasses( { - Region.class, - CountryMapper.class - } ) + @ProcessorTest + @WithClasses({ + Region.class, + CountryMapper.class + }) public void shouldHandleUpdateMethodsFromEntityToEntity() { CountryEntity source = new CountryEntity(); CountryEntity target = new CountryEntity(); @@ -128,48 +110,84 @@ public void shouldHandleUpdateMethodsFromEntityToEntity() { assertThat( target.getContinent() ).isEqualTo( Continent.EUROPE ); } - @Test - @WithClasses( { - ErroneousMapper.class, - Region.class, - } ) + @ProcessorTest + @WithClasses({ + ErroneousMapper.class, + Region.class, + }) @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, - diagnostics = { - @Diagnostic( type = ErroneousMapper.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 31, - messageRegExp = "Constant and default value are both defined in @Mapping," - + " either define a defaultValue or a constant." ), - @Diagnostic(type = ErroneousMapper.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Can't map property \".*Region region\" to \".*String region\"\\. Consider") - } + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 18, + message = "Constant and default value are both defined in @Mapping, either define a defaultValue or a" + + " constant."), + @Diagnostic(type = ErroneousMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = "Can't map property \"Region region\" to \"String region\". " + + "Consider to declare/implement a mapping method: \"String map(Region value)\".") + } ) - public void errorOnDefaultValueAndConstant() throws ParseException { + public void errorOnDefaultValueAndConstant() { + } + + @ProcessorTest + @WithClasses({ + ErroneousMapper2.class, + Region.class, + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMapper2.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 18, + message = "Expression and default value are both defined in @Mapping, either define a defaultValue or" + + " an expression."), + @Diagnostic(type = ErroneousMapper2.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = "Can't map property \"Region region\" to \"String region\". " + + "Consider to declare/implement a mapping method: \"String map(Region value)\".") + } + ) + public void errorOnDefaultValueAndExpression() { + } + + @ProcessorTest + @IssueKey("2214") + @WithClasses({ + CountryMapperMultipleSources.class, + Region.class, + }) + public void shouldBeAbleToDetermineDefaultValueBasedOnOnlyTargetType() { + CountryEntity entity = new CountryEntity(); + CountryDts target = CountryMapperMultipleSources.INSTANCE.map( entity, "ZH" ); + + assertThat( target ).isNotNull(); + assertThat( target.getCode() ).isEqualTo( "CH" ); } - @Test - @WithClasses( { - ErroneousMapper2.class, - Region.class, - } ) + @ProcessorTest + @IssueKey("2220") + @WithClasses({ + ErroneousMissingSourceMapper.class, + Region.class, + }) @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, - diagnostics = { - @Diagnostic( type = ErroneousMapper2.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 31, - messageRegExp = "Expression and default value are both defined in @Mapping," - + " either define a defaultValue or an expression." ), - @Diagnostic(type = ErroneousMapper2.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 33, - messageRegExp = "Can't map property \".*Region region\" to \".*String region\"\\. Consider") - } + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + type = ErroneousMissingSourceMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "The type of parameter \"tenant\" has no property named \"type\"." + + " Please define the source property explicitly."), + } ) - public void errorOnDefaultValueAndExpression() throws ParseException { + public void errorWhenOnlyTargetDefinedAndSourceDoesNotHaveProperty() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper.java index 9e68889648..5b218b3324 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper2.java index 144bf4ab7a..3f4ef62875 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMapper2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMissingSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMissingSourceMapper.java new file mode 100644 index 0000000000..54fd3cc645 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/ErroneousMissingSourceMapper.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.defaultvalue; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ErroneousMissingSourceMapper { + + @Mapping(target = "type", defaultValue = "STANDARD") + Tenant map(TenantDto tenant); + + class Tenant { + + private final String id; + private final String type; + + public Tenant(String id, String type) { + this.id = id; + this.type = type; + } + } + + class TenantDto { + + private final String id; + + public TenantDto(String id) { + this.id = id; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/Region.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/Region.java index 806fb93a0b..25e6bd0d50 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/Region.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/Region.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue; diff --git a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/other/Continent.java b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/other/Continent.java index 582e2e2feb..c96ed95b3d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/other/Continent.java +++ b/processor/src/test/java/org/mapstruct/ap/test/defaultvalue/other/Continent.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.defaultvalue.other; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/Address.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/Address.java index 795b79cd19..142ce54995 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/Address.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/Address.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressDto.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressDto.java index 79a2d117d1..6572fec403 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressMapper.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressMapper.java index 659e09b89c..0c384a7dd1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/AddressMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithCyclicDependency.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithCyclicDependency.java index 5d90ef2f05..fa08faa683 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithCyclicDependency.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithCyclicDependency.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithUnknownPropertyInDependsOn.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithUnknownPropertyInDependsOn.java index aae69336a1..edeb57a001 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithUnknownPropertyInDependsOn.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/ErroneousAddressMapperWithUnknownPropertyInDependsOn.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/GraphAnalyzerTest.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/GraphAnalyzerTest.java index 1f1919ca83..cbb0959b89 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/GraphAnalyzerTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/GraphAnalyzerTest.java @@ -1,33 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.HashSet; import java.util.List; import java.util.Set; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.mapstruct.ap.internal.model.dependency.GraphAnalyzer; import org.mapstruct.ap.internal.util.Strings; +import static org.assertj.core.api.Assertions.assertThat; + /** * Unit test for {@link GraphAnalyzer}. * @@ -178,7 +165,7 @@ public void eightNodesWithoutCycle() { } private Set asStrings(Set> cycles) { - Set asStrings = new HashSet(); + Set asStrings = new HashSet<>(); for ( List cycle : cycles ) { asStrings.add( asString( cycle ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/OrderingTest.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/OrderingTest.java index 9c3fdff9a1..cdf4cf6e97 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/OrderingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/OrderingTest.java @@ -1,34 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.Mapping; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for ordering mapped attributes by means of {@link Mapping#dependsOn()}. @@ -36,10 +21,9 @@ * @author Gunnar Morling */ @WithClasses({ Person.class, PersonDto.class, Address.class, AddressDto.class, AddressMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class OrderingTest { - @Test + @ProcessorTest @IssueKey("304") public void shouldApplyChainOfDependencies() { Address source = new Address(); @@ -53,7 +37,7 @@ public void shouldApplyChainOfDependencies() { assertThat( target.getFullName() ).isEqualTo( "Bob J. McRobb" ); } - @Test + @ProcessorTest @IssueKey("304") public void shouldApplySeveralDependenciesConfiguredForOneProperty() { Person source = new Person(); @@ -67,7 +51,7 @@ public void shouldApplySeveralDependenciesConfiguredForOneProperty() { assertThat( target.getFullName() ).isEqualTo( "Bob J. McRobb" ); } - @Test + @ProcessorTest @IssueKey("304") @WithClasses(ErroneousAddressMapperWithCyclicDependency.class) @ExpectedCompilationOutcome( @@ -75,16 +59,16 @@ public void shouldApplySeveralDependenciesConfiguredForOneProperty() { diagnostics = { @Diagnostic(type = ErroneousAddressMapperWithCyclicDependency.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 37, - messageRegExp = "Cycle\\(s\\) between properties given via dependsOn\\(\\): firstName -> lastName -> " - + "middleName -> firstName" + line = 24, + message = "Cycle(s) between properties given via dependsOn(): lastName -> middleName -> " + + "firstName -> lastName." ) } ) public void shouldReportErrorIfDependenciesContainCycle() { } - @Test + @ProcessorTest @IssueKey("304") @WithClasses(ErroneousAddressMapperWithUnknownPropertyInDependsOn.class) @ExpectedCompilationOutcome( @@ -92,11 +76,11 @@ public void shouldReportErrorIfDependenciesContainCycle() { diagnostics = { @Diagnostic(type = ErroneousAddressMapperWithUnknownPropertyInDependsOn.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = "\"doesnotexist\" is no property of the method return type" + line = 19, + message = "\"doesnotexist\" is no property of the method return type." ) } ) - public void shouldReportErrorIfPropertiyGivenInDependsOnDoesNotExist() { + public void shouldReportErrorIfPropertyGivenInDependsOnDoesNotExist() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/Person.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/Person.java index c2fc9fc9a8..99a0724329 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/dependency/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/dependency/PersonDto.java index 4b9c420153..0f3219080f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/dependency/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/dependency/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.dependency; diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationClassNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationClassNameMapper.java index 73861decc9..8dd010cae3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationClassNameMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationClassNameMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -29,5 +16,5 @@ public abstract class AbstractDestinationClassNameMapper { public static final AbstractDestinationClassNameMapper INSTANCE = Mappers.getMapper( AbstractDestinationClassNameMapper.class ); - public abstract String intToString(Integer source); + public abstract Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationPackageNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationPackageNameMapper.java index f2d59f3219..e26a6bbe71 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationPackageNameMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/AbstractDestinationPackageNameMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -29,5 +16,5 @@ public abstract class AbstractDestinationPackageNameMapper { public static final AbstractDestinationPackageNameMapper INSTANCE = Mappers.getMapper( AbstractDestinationPackageNameMapper.class ); - public abstract String intToString(Integer source); + public abstract Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapper.java index 2848dbbef2..99bd8915a5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -28,5 +15,5 @@ public interface DestinationClassNameMapper { DestinationClassNameMapper INSTANCE = Mappers.getMapper( DestinationClassNameMapper.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperConfig.java index 7c3bc5ccf1..d0d00154b0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorated.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorated.java index 494c876cbf..454e5e15bc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorated.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorated.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -30,5 +17,5 @@ public interface DestinationClassNameMapperDecorated { DestinationClassNameMapperDecorated INSTANCE = Mappers.getMapper( DestinationClassNameMapperDecorated.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorator.java index cd4ef10b9f..3ba1433e21 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -29,7 +16,7 @@ protected DestinationClassNameMapperDecorator(DestinationClassNameMapperDecorate } @Override - public String intToString(Integer source) { - return delegate.intToString( source ); + public Target map(Integer source) { + return delegate.map( source ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfig.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfig.java index d0fba5a6cd..d13675f0ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -28,5 +15,5 @@ public interface DestinationClassNameMapperWithConfig { DestinationClassNameMapperWithConfig INSTANCE = Mappers.getMapper( DestinationClassNameMapperWithConfig.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfigOverride.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfigOverride.java index 15bdad4d20..a3f845462b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfigOverride.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameMapperWithConfigOverride.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -29,5 +16,5 @@ public interface DestinationClassNameMapperWithConfigOverride { DestinationClassNameMapperWithConfigOverride INSTANCE = Mappers.getMapper( DestinationClassNameMapperWithConfigOverride.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameTest.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameTest.java index 6b80061046..1f6e255b95 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameTest.java @@ -1,52 +1,39 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxInject; import org.mapstruct.factory.Mappers; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + /** * @author Christophe Labouisse on 27/05/2015. */ -@RunWith(AnnotationProcessorTestRunner.class) +@WithClasses( Target.class ) public class DestinationClassNameTest { - @Test + @ProcessorTest @WithClasses({ DestinationClassNameMapper.class }) - public void shouldGenerateRightName() throws Exception { + public void shouldGenerateRightName() { DestinationClassNameMapper instance = DestinationClassNameMapper.INSTANCE; assertThat( instance.getClass().getSimpleName() ).isEqualTo( "MyDestinationClassNameMapperCustomImpl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationClassNameWithJsr330Mapper.class }) + @WithJavaxInject public void shouldNotGenerateSpi() throws Exception { Class clazz = DestinationClassNameWithJsr330Mapper.class; try { Mappers.getMapper( clazz ); - Assert.fail( "Should have thrown an ClassNotFoundException" ); + fail( "Should have thrown an ClassNotFoundException" ); } catch ( RuntimeException e ) { assertThat( e.getCause() ).isNotNull() @@ -59,25 +46,25 @@ public void shouldNotGenerateSpi() throws Exception { assertThat( instance.getClass().getSimpleName() ).isEqualTo( "DestinationClassNameWithJsr330MapperJsr330Impl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationClassNameMapperConfig.class, DestinationClassNameMapperWithConfig.class }) - public void shouldGenerateRightNameWithConfig() throws Exception { + public void shouldGenerateRightNameWithConfig() { DestinationClassNameMapperWithConfig instance = DestinationClassNameMapperWithConfig.INSTANCE; assertThat( instance.getClass().getSimpleName() ) .isEqualTo( "MyDestinationClassNameMapperWithConfigConfigImpl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationClassNameMapperConfig.class, DestinationClassNameMapperWithConfigOverride.class }) - public void shouldGenerateRightNameWithConfigOverride() throws Exception { + public void shouldGenerateRightNameWithConfigOverride() { DestinationClassNameMapperWithConfigOverride instance = DestinationClassNameMapperWithConfigOverride.INSTANCE; assertThat( instance.getClass().getSimpleName() ) .isEqualTo( "CustomDestinationClassNameMapperWithConfigOverrideMyImpl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationClassNameMapperDecorated.class, DestinationClassNameMapperDecorator.class }) - public void shouldGenerateRightNameWithDecorator() throws Exception { + public void shouldGenerateRightNameWithDecorator() { DestinationClassNameMapperDecorated instance = DestinationClassNameMapperDecorated.INSTANCE; assertThat( instance.getClass().getSimpleName() ) .isEqualTo( "MyDestinationClassNameMapperDecoratedCustomImpl" ); @@ -86,7 +73,7 @@ public void shouldGenerateRightNameWithDecorator() throws Exception { .isEqualTo( "MyDestinationClassNameMapperDecoratedCustomImpl_" ); } - @Test + @ProcessorTest @WithClasses({ AbstractDestinationClassNameMapper.class, AbstractDestinationPackageNameMapper.class }) public void shouldWorkWithAbstractClasses() { AbstractDestinationClassNameMapper mapper1 = AbstractDestinationClassNameMapper.INSTANCE; diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameWithJsr330Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameWithJsr330Mapper.java index 40f4ce43ea..3358f68fd4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameWithJsr330Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationClassNameWithJsr330Mapper.java @@ -1,29 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; /** * @author Christophe Labouisse on 27/05/2015. */ -@Mapper(implementationName = "Jsr330Impl", componentModel = "jsr330") +@Mapper(implementationName = "Jsr330Impl", componentModel = MappingConstants.ComponentModel.JSR330) public interface DestinationClassNameWithJsr330Mapper { - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapper.java index 942d890898..c049036a13 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -28,5 +15,5 @@ public interface DestinationPackageNameMapper { DestinationPackageNameMapper INSTANCE = Mappers.getMapper( DestinationPackageNameMapper.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperConfig.java index 3be6e29fc0..9bb64eddbf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorated.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorated.java index 3b48aa4a92..98f6236027 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorated.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorated.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -30,5 +17,5 @@ public interface DestinationPackageNameMapperDecorated { DestinationPackageNameMapperDecorated INSTANCE = Mappers.getMapper( DestinationPackageNameMapperDecorated.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorator.java index 92263df6a8..667bd99349 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -29,7 +16,7 @@ protected DestinationPackageNameMapperDecorator(DestinationPackageNameMapperDeco } @Override - public String intToString(Integer source) { - return delegate.intToString( source ); + public Target map(Integer source) { + return delegate.map( source ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfig.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfig.java index 9e24c6ddfd..6a5a870520 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -28,5 +15,5 @@ public interface DestinationPackageNameMapperWithConfig { DestinationPackageNameMapperWithConfig INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithConfig.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfigOverride.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfigOverride.java index e55bc764c8..79699006b1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfigOverride.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithConfigOverride.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -29,5 +16,5 @@ public interface DestinationPackageNameMapperWithConfigOverride { DestinationPackageNameMapperWithConfigOverride INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithConfigOverride.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithSuffix.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithSuffix.java index d38afd83bc..068f30331d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithSuffix.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameMapperWithSuffix.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; @@ -28,5 +15,5 @@ public interface DestinationPackageNameMapperWithSuffix { DestinationPackageNameMapperWithSuffix INSTANCE = Mappers.getMapper( DestinationPackageNameMapperWithSuffix.class ); - String intToString(Integer source); + Target map(Integer source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameTest.java b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameTest.java index b94c8326c0..5e02c88d93 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/DestinationPackageNameTest.java @@ -1,64 +1,49 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.destination; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Christophe Labouisse on 27/05/2015. */ @IssueKey( "556" ) -@RunWith(AnnotationProcessorTestRunner.class) +@WithClasses( Target.class ) public class DestinationPackageNameTest { - @Test + @ProcessorTest @WithClasses({ DestinationPackageNameMapper.class }) - public void shouldGenerateInRightPackage() throws Exception { + public void shouldGenerateInRightPackage() { DestinationPackageNameMapper instance = DestinationPackageNameMapper.INSTANCE; assertThat( instance.getClass().getName() ) .isEqualTo( "org.mapstruct.ap.test.destination.dest.DestinationPackageNameMapperImpl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationPackageNameMapperWithSuffix.class }) - public void shouldGenerateInRightPackageWithSuffix() throws Exception { + public void shouldGenerateInRightPackageWithSuffix() { DestinationPackageNameMapperWithSuffix instance = DestinationPackageNameMapperWithSuffix.INSTANCE; assertThat( instance.getClass().getName() ) .isEqualTo( "org.mapstruct.ap.test.destination.dest.DestinationPackageNameMapperWithSuffixMyImpl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationPackageNameMapperConfig.class, DestinationPackageNameMapperWithConfig.class }) - public void shouldGenerateRightSuffixWithConfig() throws Exception { + public void shouldGenerateRightSuffixWithConfig() { DestinationPackageNameMapperWithConfig instance = DestinationPackageNameMapperWithConfig.INSTANCE; assertThat( instance.getClass().getName() ) .isEqualTo( "org.mapstruct.ap.test.destination.dest.DestinationPackageNameMapperWithConfigImpl" ); } - @Test + @ProcessorTest @WithClasses({ DestinationPackageNameMapperConfig.class, DestinationPackageNameMapperWithConfigOverride.class }) - public void shouldGenerateRightSuffixWithConfigOverride() throws Exception { + public void shouldGenerateRightSuffixWithConfigOverride() { DestinationPackageNameMapperWithConfigOverride instance = DestinationPackageNameMapperWithConfigOverride.INSTANCE; assertThat( instance.getClass().getName() ) @@ -67,9 +52,9 @@ public void shouldGenerateRightSuffixWithConfigOverride() throws Exception { ); } - @Test + @ProcessorTest @WithClasses({ DestinationPackageNameMapperDecorated.class, DestinationPackageNameMapperDecorator.class }) - public void shouldGenerateRightSuffixWithDecorator() throws Exception { + public void shouldGenerateRightSuffixWithDecorator() { DestinationPackageNameMapperDecorated instance = DestinationPackageNameMapperDecorated.INSTANCE; assertThat( instance.getClass().getName() ) .isEqualTo( "org.mapstruct.ap.test.destination.dest.DestinationPackageNameMapperDecoratedImpl" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/destination/Target.java b/processor/src/test/java/org/mapstruct/ap/test/destination/Target.java new file mode 100644 index 0000000000..5b3bb4ba34 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/destination/Target.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.destination; + +public class Target { + + private final Integer source; + + public Target(Integer source) { + this.source = source; + } + + public Integer getSource() { + return source; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTarget.java b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTarget.java new file mode 100644 index 0000000000..f1b3a0f073 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTarget.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.emptytarget; + +public class EmptyTarget { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTargetMapper.java new file mode 100644 index 0000000000..8c82f81b7b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTargetMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.emptytarget; + +import org.mapstruct.Mapper; + +@Mapper +public interface EmptyTargetMapper { + + TargetWithNoSetters mapToTargetWithSetters(Source source); + + EmptyTarget mapToEmptyTarget(Source source); + + Target mapToTarget(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTargetTest.java b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTargetTest.java new file mode 100644 index 0000000000..66fa65b796 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/EmptyTargetTest.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.emptytarget; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +@IssueKey("1140") +@WithClasses({ + EmptyTarget.class, + EmptyTargetMapper.class, + Source.class, + Target.class, + TargetWithNoSetters.class, +}) +class EmptyTargetTest { + + @ProcessorTest + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = EmptyTargetMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 13, + message = "No target property found for target \"TargetWithNoSetters\"."), + @Diagnostic(type = EmptyTargetMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 15, + message = "No target property found for target \"EmptyTarget\".") + }) + void shouldProvideWarnings() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/emptytarget/Source.java b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/Source.java new file mode 100644 index 0000000000..643cdccf3a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/Source.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.emptytarget; + +public class Source { + private String label; + private double weight; + private Object content; + + public Object getContent() { + return content; + } + + public void setContent(Object content) { + this.content = content; + } + + public double getWeight() { + return weight; + } + + public void setWeight(double weight) { + this.weight = weight; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/emptytarget/Target.java b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/Target.java new file mode 100644 index 0000000000..488a1fa8a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/Target.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.emptytarget; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private final String label; + private final double weight; + private final Object content; + + public Target(String label, double weight, Object content) { + this.label = label; + this.weight = weight; + this.content = content; + } + + public String getLabel() { + return label; + } + + public double getWeight() { + return weight; + } + + public Object getContent() { + return content; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/emptytarget/TargetWithNoSetters.java b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/TargetWithNoSetters.java new file mode 100644 index 0000000000..edeb80f0d5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/emptytarget/TargetWithNoSetters.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.emptytarget; + +public class TargetWithNoSetters { + private int flightNumber; + private String airplaneName; + + public String getAirplaneName() { + return airplaneName; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java deleted file mode 100644 index 632c171017..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/EnumMappingTest.java +++ /dev/null @@ -1,167 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -import static org.assertj.core.api.Assertions.assertThat; - -import javax.tools.Diagnostic.Kind; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mapstruct.ap.testutil.IssueKey; -import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; -import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; -import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; - -/** - * Test for the generation and invocation of enum mapping methods. - * - * @author Gunnar Morling - */ -@IssueKey("128") -@WithClasses({ OrderEntity.class, OrderType.class, OrderDto.class, ExternalOrderType.class }) -@RunWith(AnnotationProcessorTestRunner.class) -public class EnumMappingTest { - - @Test - @WithClasses( OrderMapper.class ) - @ExpectedCompilationOutcome( - value = CompilationResult.SUCCEEDED, - diagnostics = { - @Diagnostic(type = OrderMapper.class, - kind = Kind.WARNING, - line = 41, - messageRegExp = "Mapping of Enums via @Mapping is going to be removed in future versions of " - + "MapStruct\\. Please use @ValueMapping instead!") - } - ) - public void shouldGenerateEnumMappingMethod() { - ExternalOrderType target = OrderMapper.INSTANCE.orderTypeToExternalOrderType( OrderType.B2B ); - assertThat( target ).isEqualTo( ExternalOrderType.B2B ); - - target = OrderMapper.INSTANCE.orderTypeToExternalOrderType( OrderType.RETAIL ); - assertThat( target ).isEqualTo( ExternalOrderType.RETAIL ); - } - - @Test - @WithClasses(OrderMapper.class) - @ExpectedCompilationOutcome( - value = CompilationResult.SUCCEEDED, - diagnostics = { - @Diagnostic(type = OrderMapper.class, - kind = Kind.WARNING, - line = 41, - messageRegExp = "Mapping of Enums via @Mapping is going to be removed in future versions of " - + "MapStruct\\. Please use @ValueMapping instead!") - } - ) - public void shouldConsiderConstantMappings() { - ExternalOrderType target = OrderMapper.INSTANCE.orderTypeToExternalOrderType( OrderType.EXTRA ); - assertThat( target ).isEqualTo( ExternalOrderType.SPECIAL ); - - target = OrderMapper.INSTANCE.orderTypeToExternalOrderType( OrderType.STANDARD ); - assertThat( target ).isEqualTo( ExternalOrderType.DEFAULT ); - - target = OrderMapper.INSTANCE.orderTypeToExternalOrderType( OrderType.NORMAL ); - assertThat( target ).isEqualTo( ExternalOrderType.DEFAULT ); - } - - @Test - @WithClasses( OrderMapper.class ) - @ExpectedCompilationOutcome( - value = CompilationResult.SUCCEEDED, - diagnostics = { - @Diagnostic(type = OrderMapper.class, - kind = Kind.WARNING, - line = 41, - messageRegExp = "Mapping of Enums via @Mapping is going to be removed in future versions of " - + "MapStruct\\. Please use @ValueMapping instead!") - } - ) - public void shouldInvokeEnumMappingMethodForPropertyMapping() { - OrderEntity order = new OrderEntity(); - order.setOrderType( OrderType.EXTRA ); - - OrderDto orderDto = OrderMapper.INSTANCE.orderEntityToDto( order ); - assertThat( orderDto ).isNotNull(); - assertThat( orderDto.getOrderType() ).isEqualTo( ExternalOrderType.SPECIAL ); - } - - @Test - @WithClasses( ErroneousOrderMapperMappingSameConstantTwice.class ) - @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, - diagnostics = { - - @Diagnostic(type = ErroneousOrderMapperMappingSameConstantTwice.class, - kind = Kind.ERROR, - line = 42, - messageRegExp = "One enum constant must not be mapped to more than one target constant, but " + - "constant EXTRA is mapped to SPECIAL, DEFAULT\\."), - @Diagnostic(type = ErroneousOrderMapperMappingSameConstantTwice.class, - kind = Kind.WARNING, - line = 42, - messageRegExp = "Mapping of Enums via @Mapping is going to be removed in future versions of " - + "MapStruct\\. Please use @ValueMapping instead!") - } - ) - public void shouldRaiseErrorIfSameSourceEnumConstantIsMappedTwice() { - } - - @Test - @WithClasses(ErroneousOrderMapperUsingUnknownEnumConstants.class) - @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, - diagnostics = { - @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, - kind = Kind.WARNING, - line = 40, - messageRegExp = "Mapping of Enums via @Mapping is going to be removed in future versions of " - + "MapStruct\\. Please use @ValueMapping instead!"), - @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, - kind = Kind.ERROR, - line = 37, - messageRegExp = "Constant FOO doesn't exist in enum type org.mapstruct.ap.test.enums.OrderType\\."), - @Diagnostic(type = ErroneousOrderMapperUsingUnknownEnumConstants.class, - kind = Kind.ERROR, - line = 38, - messageRegExp = "Constant BAR doesn't exist in enum type org.mapstruct.ap.test.enums." + - "ExternalOrderType\\.") - } - ) - public void shouldRaiseErrorIfUnknownEnumConstantsAreSpecifiedInMapping() { - } - - @Test - @WithClasses(ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.class) - @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, - diagnostics = { - @Diagnostic(type = ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.class, - kind = Kind.ERROR, - line = 34, - messageRegExp = "The following constants from the source enum have no corresponding constant in the " + - "target enum and must be be mapped via adding additional mappings: EXTRA, STANDARD, NORMAL") - } - ) - public void shouldRaiseErrorIfSourceConstantWithoutMatchingConstantInTargetTypeIsNotMapped() { - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java deleted file mode 100644 index 5c0f514b36..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperMappingSameConstantTwice.java +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -/** - * @author Gunnar Morling - */ -@Mapper -public interface ErroneousOrderMapperMappingSameConstantTwice { - - ErroneousOrderMapperMappingSameConstantTwice INSTANCE = Mappers.getMapper( - ErroneousOrderMapperMappingSameConstantTwice.class - ); - - @Mappings({ - @Mapping(source = "EXTRA", target = "SPECIAL"), - @Mapping(source = "EXTRA", target = "DEFAULT"), - @Mapping(source = "STANDARD", target = "DEFAULT"), - @Mapping(source = "NORMAL", target = "DEFAULT") - }) - ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java deleted file mode 100644 index a8e6c999b7..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -import org.mapstruct.Mapper; -import org.mapstruct.factory.Mappers; - -/** - * @author Gunnar Morling - */ -@Mapper -public interface ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType { - - ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType INSTANCE = Mappers.getMapper( - ErroneousOrderMapperNotMappingConstantWithoutMatchInTargetType.class - ); - - ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperUsingUnknownEnumConstants.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperUsingUnknownEnumConstants.java deleted file mode 100644 index a4520b5e14..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/ErroneousOrderMapperUsingUnknownEnumConstants.java +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -/** - * @author Gunnar Morling - */ -@Mapper -public interface ErroneousOrderMapperUsingUnknownEnumConstants { - - ErroneousOrderMapperUsingUnknownEnumConstants INSTANCE = Mappers.getMapper( - ErroneousOrderMapperUsingUnknownEnumConstants.class - ); - - @Mappings({ - @Mapping(source = "FOO", target = "SPECIAL"), - @Mapping(source = "EXTRA", target = "BAR") - }) - ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/ExternalOrderType.java b/processor/src/test/java/org/mapstruct/ap/test/enums/ExternalOrderType.java deleted file mode 100644 index 2388a05f90..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/ExternalOrderType.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -/** - * @author Gunnar Morling - */ -public enum ExternalOrderType { - - RETAIL, B2B, SPECIAL, DEFAULT -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderDto.java b/processor/src/test/java/org/mapstruct/ap/test/enums/OrderDto.java deleted file mode 100644 index 97c9359713..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderDto.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -/** - * @author Gunnar Morling - */ -public class OrderDto { - - private ExternalOrderType orderType; - - public ExternalOrderType getOrderType() { - return orderType; - } - - public void setOrderType(ExternalOrderType orderType) { - this.orderType = orderType; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderEntity.java b/processor/src/test/java/org/mapstruct/ap/test/enums/OrderEntity.java deleted file mode 100644 index bc9136ec97..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderEntity.java +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -/** - * @author Gunnar Morling - */ -public class OrderEntity { - - private OrderType orderType; - - public OrderType getOrderType() { - return orderType; - } - - public void setOrderType(OrderType orderType) { - this.orderType = orderType; - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/enums/OrderMapper.java deleted file mode 100644 index c6a3e5e7e8..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderMapper.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -import org.mapstruct.Mapper; -import org.mapstruct.Mapping; -import org.mapstruct.Mappings; -import org.mapstruct.factory.Mappers; - -/** - * @author Gunnar Morling - */ -@Mapper -public interface OrderMapper { - - OrderMapper INSTANCE = Mappers.getMapper( OrderMapper.class ); - - OrderDto orderEntityToDto(OrderEntity order); - - @Mappings({ - @Mapping(source = "EXTRA", target = "SPECIAL"), - @Mapping(source = "STANDARD", target = "DEFAULT"), - @Mapping(source = "NORMAL", target = "DEFAULT") - }) - ExternalOrderType orderTypeToExternalOrderType(OrderType orderType); -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderType.java b/processor/src/test/java/org/mapstruct/ap/test/enums/OrderType.java deleted file mode 100644 index e1f3625d05..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/enums/OrderType.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.enums; - -/** - * @author Gunnar Morling - */ -public enum OrderType { - - RETAIL, B2B, EXTRA, STANDARD, NORMAL -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousAnnotatedFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousAnnotatedFactoryTest.java index 24c25d8858..99fd2b98cd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousAnnotatedFactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousAnnotatedFactoryTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Remo Meier @@ -33,28 +18,19 @@ Bar.class, Foo.class, AmbiguousBarFactory.class, Source.class, SourceTargetMapperAndBarFactory.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class AmbiguousAnnotatedFactoryTest { - @Test + @ProcessorTest @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = SourceTargetMapperAndBarFactory.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = "Ambiguous factory methods found for creating " - + "org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod.Bar: " - + "org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod.Bar " - + "createBar\\(org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod.Foo foo\\), " - + "org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod.Bar " - + ".*AmbiguousBarFactory.createBar\\(org.mapstruct.ap.test.erroneous." - + "ambiguousannotatedfactorymethod.Foo foo\\)."), - @Diagnostic(type = SourceTargetMapperAndBarFactory.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = ".*\\.ambiguousannotatedfactorymethod.Bar does not have an accessible parameterless " + - "constructor\\.") + line = 22, + message = "Ambiguous factory methods found for creating Bar: " + + "Bar createBar(Foo foo), " + + "Bar AmbiguousBarFactory.createBar(Foo foo)." + + " See https://mapstruct.org/faq/#ambiguous for more info.") } ) diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousBarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousBarFactory.java index 80c67f79c3..2c6c070402 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousBarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/AmbiguousBarFactory.java @@ -1,26 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; import org.mapstruct.ObjectFactory; - /** * @author Remo Meier */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Bar.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Bar.java index ab2a15b6d2..ebbd3be29e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Bar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Bar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Foo.java index 2560d84321..679efa8358 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Foo.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; - /** * @author Remo Meier */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Source.java index 5b5aafdf63..0a4e64dc54 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Source.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; - /** * @author Remo Meier */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/SourceTargetMapperAndBarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/SourceTargetMapperAndBarFactory.java index b55ac6e603..4b7e67d71b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/SourceTargetMapperAndBarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/SourceTargetMapperAndBarFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Target.java index 708972fd42..f15dc0e8d6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousannotatedfactorymethod/Target.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousannotatedfactorymethod; - /** * @author Remo Meier */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Bar.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Bar.java index 654630bf1f..50bef91496 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Bar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Bar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/FactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/FactoryTest.java index c35ed41a03..b9ae5b8ffa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/FactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/FactoryTest.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.a.BarFactory; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Sjaak Derksen @@ -36,27 +21,20 @@ Bar.class, Foo.class, BarFactory.class, Source.class, SourceTargetMapperAndBarFactory.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class FactoryTest { - @Test + @ProcessorTest @IssueKey("81") @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = SourceTargetMapperAndBarFactory.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = "Ambiguous factory methods found for creating " - + "org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar: " - + "org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar createBar\\(\\), " - + "org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar .*BarFactory.createBar\\(\\)."), - @Diagnostic(type = SourceTargetMapperAndBarFactory.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = ".*\\.ambiguousfactorymethod\\.Bar does not have an accessible parameterless " - + "constructor\\.") - + line = 22, + message = "Ambiguous factory methods found for creating Bar: " + + "Bar createBar(), " + + "Bar BarFactory.createBar()." + + " See https://mapstruct.org/faq/#ambiguous for more info.") } ) public void shouldUseTwoFactoryMethods() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Foo.java index 914570ac0d..7d13089921 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Foo.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Source.java index df6ffab916..2aabe7e06d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Source.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/SourceTargetMapperAndBarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/SourceTargetMapperAndBarFactory.java index 9c308a8a29..0e4e5a6fd8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/SourceTargetMapperAndBarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/SourceTargetMapperAndBarFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Target.java index 0d240301cd..025ae810f8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/Target.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/a/BarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/a/BarFactory.java index b849f80516..b0e2a46e48 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/a/BarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousfactorymethod/a/BarFactory.java @@ -1,26 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.a; import org.mapstruct.ap.test.erroneous.ambiguousfactorymethod.Bar; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/AmbiguousMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/AmbiguousMapperTest.java new file mode 100644 index 0000000000..c3fa15b244 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/AmbiguousMapperTest.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.ambiguousmapping; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; + +@IssueKey("2156") +public class AmbiguousMapperTest { + + @ProcessorTest + @WithClasses( ErroneousWithAmbiguousMethodsMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousWithAmbiguousMethodsMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = + "Ambiguous mapping methods found for mapping property " + + "\"ErroneousWithAmbiguousMethodsMapper.LeafDTO branch.leaf\" to ErroneousWithAmbiguousMethodsMapper.LeafEntity: " + + "ErroneousWithAmbiguousMethodsMapper.LeafEntity map1(ErroneousWithAmbiguousMethodsMapper.LeafDTO dto), " + + "ErroneousWithAmbiguousMethodsMapper.LeafEntity map2(ErroneousWithAmbiguousMethodsMapper.LeafDTO dto). " + + "See https://mapstruct.org/faq/#ambiguous for more info." ) + } + ) + public void testErrorMessageForAmbiguous() { + } + + @ProcessorTest + @WithClasses( ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = + // CHECKSTYLE:OFF + "Ambiguous mapping methods found for mapping property \"ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO branch.leaf\" to " + + "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity: " + + "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map1(ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map2(ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map3(ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map4(ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map5(ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto)" + + "... and 1 more. See https://mapstruct.org/faq/#ambiguous for more info." + // CHECKSTYLE:ON + ) + } + ) + public void testErrorMessageForManyAmbiguous() { + } + + @ProcessorTest + @ProcessorOption(name = "mapstruct.verbose", value = "true") + @WithClasses( ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = + // CHECKSTYLE:OFF + "Ambiguous mapping methods found for mapping property \"org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO branch.leaf\" " + + "to org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity: " + + "org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map1(org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map2(org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map3(org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map4(org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map5(org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto), " + + "org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafEntity map6(org.mapstruct.ap.test.erroneous.ambiguousmapping.ErroneousWithMoreThanFiveAmbiguousMethodsMapper.LeafDTO dto). " + + "See https://mapstruct.org/faq/#ambiguous for more info." + // CHECKSTYLE:ON + ) + } + ) + public void testErrorMessageForManyAmbiguousVerbose() { + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/ErroneousWithAmbiguousMethodsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/ErroneousWithAmbiguousMethodsMapper.java new file mode 100644 index 0000000000..165f8d5945 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/ErroneousWithAmbiguousMethodsMapper.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.ambiguousmapping; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ErroneousWithAmbiguousMethodsMapper { + + ErroneousWithAmbiguousMethodsMapper INSTANCE = Mappers.getMapper( ErroneousWithAmbiguousMethodsMapper.class ); + + TrunkEntity map(TrunkDTO dto); + + default LeafEntity map1(LeafDTO dto) { + return new LeafEntity(); + } + + // duplicated method, triggering ambiguous mapping method + default LeafEntity map2(LeafDTO dto) { + return new LeafEntity(); + } + + // CHECKSTYLE:OFF + class TrunkDTO { + public BranchDTO branch; + } + + class BranchDTO { + public LeafDTO leaf; + } + + class LeafDTO { + public int numberOfVeigns; + } + + class TrunkEntity { + public BranchEntity branch; + } + + class BranchEntity { + public LeafEntity leaf; + } + + class LeafEntity { + public int numberOfVeigns; + } + // CHECKSTYLE ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/ErroneousWithMoreThanFiveAmbiguousMethodsMapper.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/ErroneousWithMoreThanFiveAmbiguousMethodsMapper.java new file mode 100644 index 0000000000..2ca70ccaf4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/ambiguousmapping/ErroneousWithMoreThanFiveAmbiguousMethodsMapper.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.ambiguousmapping; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ErroneousWithMoreThanFiveAmbiguousMethodsMapper { + + ErroneousWithMoreThanFiveAmbiguousMethodsMapper + INSTANCE = Mappers.getMapper( ErroneousWithMoreThanFiveAmbiguousMethodsMapper.class ); + + TrunkEntity map(TrunkDTO dto); + + default LeafEntity map1(LeafDTO dto) { + return new LeafEntity(); + } + + // duplicated method, triggering ambiguous mapping method + default LeafEntity map2(LeafDTO dto) { + return new LeafEntity(); + } + + // duplicated method, triggering ambiguous mapping method + default LeafEntity map3(LeafDTO dto) { + return new LeafEntity(); + } + + // duplicated method, triggering ambiguous mapping method + default LeafEntity map4(LeafDTO dto) { + return new LeafEntity(); + } + + // duplicated method, triggering ambiguous mapping method + + default LeafEntity map5(LeafDTO dto) { + return new LeafEntity(); + } + + // duplicated method, triggering ambiguous mapping method + default LeafEntity map6(LeafDTO dto) { + return new LeafEntity(); + } + + // CHECKSTYLE:OFF + class TrunkDTO { + public BranchDTO branch; + } + + class BranchDTO { + public LeafDTO leaf; + } + + class LeafDTO { + public int numberOfVeigns; + } + + class TrunkEntity { + public BranchEntity branch; + } + + class BranchEntity { + public LeafEntity leaf; + } + + class LeafEntity { + public int numberOfVeigns; + } + // CHECKSTYLE ON +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java index 4b55a0bd28..8a5ffefe6d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/AnnotationNotFoundTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.annotationnotfound; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Test for (custom / external) annotation that is not on class path @@ -35,17 +20,16 @@ * @author Sjaak Derksen */ @WithClasses( { Source.class, Target.class, ErroneousMapper.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class AnnotationNotFoundTest { - @Test + @ProcessorTest @IssueKey( "298" ) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic( type = ErroneousMapper.class, kind = Kind.ERROR, - line = 30, + line = 17, messageRegExp = "NotFoundAnnotation") } ) diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/ErroneousMapper.java index 081a3e94c8..d9314cf8f8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/ErroneousMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/ErroneousMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.annotationnotfound; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/NotFoundAnnotation.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/NotFoundAnnotation.java index c1bc59b1c3..d1f476c8a5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/NotFoundAnnotation.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/NotFoundAnnotation.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.annotationnotfound; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Source.java index ae57f63e5f..ee23f10709 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.annotationnotfound; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Target.java index 81a5267eaf..393d061ea8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/annotationnotfound/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.annotationnotfound; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/AnotherTarget.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/AnotherTarget.java index d7ca42c866..86c862d59f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/AnotherTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/AnotherTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/DummySource.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/DummySource.java index 6f1d88988c..4a668f918f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/DummySource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/DummySource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper.java index 57484a6e22..d7e230547a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; @@ -26,11 +13,15 @@ public interface ErroneousMapper { @Mappings({ - @Mapping(source = "bar", target = "foo"), - @Mapping(source = "source1.foo", target = "foo"), - @Mapping(source = "foo", target = "bar") + @Mapping(target = "foo", source = "bar"), + @Mapping(target = "foo", source = "source1.foo" ), + @Mapping(target = "bar", source = "foo") }) Target sourceToTarget(Source source); + // to test that nested is also reported correctly + @Mapping(target = "foo", source = "source1.foo" ) + Target sourceToTarget2(Source source); + AnotherTarget sourceToAnotherTarget(Source source); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper1.java index ce7bbeeae9..502ac44b1f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper1.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper1.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; @@ -26,7 +13,7 @@ public interface ErroneousMapper1 { @Mappings({ - @Mapping(source = "source.foobar", target = "foo") + @Mapping(target = "foo", source = "source.foobar") }) Target sourceToTarget(Source source, DummySource source1); diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper2.java index 698a7509d3..0dea78c6f8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMapper2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMappingsTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMappingsTest.java index cc3ea1fb40..0d040f7366 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMappingsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/ErroneousMappingsTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Test for using unknown attributes in {@code @Mapping}. @@ -35,10 +20,9 @@ * @author Gunnar Morling */ @WithClasses({ Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ErroneousMappingsTest { - @Test + @ProcessorTest @IssueKey("11") @WithClasses( { ErroneousMapper.class, AnotherTarget.class } ) @ExpectedCompilationOutcome( @@ -46,55 +30,54 @@ public class ErroneousMappingsTest { diagnostics = { @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 29, - messageRegExp = "No property named \"bar\" exists in source parameter\\(s\\)\\. " + - "Did you mean \"foo\"?"), + line = 20, + message = "Target property \"foo\" must not be mapped more than once."), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "No property named \"source1.foo\" exists in source parameter\\(s\\)\\. " + + line = 16, + message = "No property named \"bar\" exists in source parameter(s). " + "Did you mean \"foo\"?"), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 31, - messageRegExp = "Unknown property \"bar\" in result type " + - "org.mapstruct.ap.test.erroneous.attributereference.Target. Did you mean \"foo\"?"), + line = 18, + message = "Unknown property \"bar\" in result type Target. Did you mean \"foo\"?"), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 33, - messageRegExp = "Target property \"foo\" must not be mapped more than once"), + line = 23, + message = "No property named \"source1.foo\" exists in source parameter(s). " + + "Did you mean \"foo\"?"), @Diagnostic(type = ErroneousMapper.class, kind = Kind.WARNING, - line = 35, - messageRegExp = "Unmapped target property: \"bar\"") + line = 26, + message = "Unmapped target property: \"bar\".") } ) public void shouldFailToGenerateMappings() { } - @Test + @ProcessorTest @WithClasses( { ErroneousMapper1.class, DummySource.class } ) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousMapper1.class, kind = Kind.ERROR, - line = 29, - messageRegExp = "The type of parameter \"source\" has no property named \"foobar\"") + line = 16, + message = "The type of parameter \"source\" has no property named \"foobar\".") } ) public void shouldFailToGenerateMappingsErrorOnMandatoryParameterName() { } - @Test + @ProcessorTest @WithClasses( { ErroneousMapper2.class } ) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousMapper2.class, kind = Kind.ERROR, - line = 32, - messageRegExp = "Target property \"foo\" must not be mapped more than once" ) + line = 19, + message = "Target property \"foo\" must not be mapped more than once." ) } ) public void shouldFailToGenerateMappingsErrorOnDuplicateTarget() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Source.java index 1b1d13ebf0..9aedfa24ee 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Target.java index e0804545b2..2ce74b5f9b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/attributereference/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.attributereference; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MapperWithMalformedExpression.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MapperWithMalformedExpression.java index 7fb159871f..83b1dbbbb7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MapperWithMalformedExpression.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MapperWithMalformedExpression.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.misbalancedbraces; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MisbalancedBracesTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MisbalancedBracesTest.java index 97353ad811..f3f6e2417a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MisbalancedBracesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/MisbalancedBracesTest.java @@ -1,34 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.misbalancedbraces; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.DisableCheckstyle; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Test for making sure that expressions with too many closing braces are passed through, letting the compiler raise an @@ -38,12 +23,11 @@ */ @WithClasses({ MapperWithMalformedExpression.class, Source.class, Target.class }) @DisableCheckstyle -@RunWith(AnnotationProcessorTestRunner.class) public class MisbalancedBracesTest { // the compiler messages due to the additional closing brace differ between JDK and Eclipse, hence we can only // assert on the line number but not the message - @Test + @ProcessorTest @IssueKey("1056") @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Source.java index be8bcbbac0..f7f58ac980 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.misbalancedbraces; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Target.java index d7fc738177..f68b211c59 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/misbalancedbraces/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.misbalancedbraces; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper1.java new file mode 100644 index 0000000000..1e4bc62c29 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper1.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface ErroneousMapper1 { + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "property", source = "source" ) + Target map( Source source ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper2.java new file mode 100644 index 0000000000..34802a0c73 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper2.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface ErroneousMapper2 { + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "nameBasedSource" ) + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper3.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper3.java new file mode 100644 index 0000000000..b8d04aa5bb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper3.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface ErroneousMapper3 { + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "constant", constant = "constant" ) + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper4.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper4.java new file mode 100644 index 0000000000..7e9f1ee85a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousMapper4.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper +public interface ErroneousMapper4 { + + @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "property", source = "source" ) + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousPropertyMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousPropertyMappingTest.java new file mode 100644 index 0000000000..43d7dfca5b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/ErroneousPropertyMappingTest.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +@IssueKey("1504") +@WithClasses({ Source.class, Target.class, UnmappableClass.class }) +public class ErroneousPropertyMappingTest { + + @ProcessorTest + @WithClasses(ErroneousMapper1.class) + @IssueKey("1504") + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Can't map property \"UnmappableClass source\" to \"String property\". " + + "Consider to declare/implement a mapping method: \"String map(UnmappableClass value)\".") + } + ) + public void testUnmappableSourceProperty() { + } + + @ProcessorTest + @WithClasses(ErroneousMapper2.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Can't map property \"UnmappableClass nameBasedSource\" to \"String nameBasedSource\"." + + " Consider to declare/implement a mapping method: \"String map(UnmappableClass value)\".") + } + ) + public void testUnmappableSourcePropertyWithNoSourceDefinedInMapping() { + } + + @ProcessorTest + @WithClasses(ErroneousMapper3.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Can't map \"constant\" to \"UnmappableClass constant\".") + } + ) + public void testUnmappableConstantAssignment() { + } + + @ProcessorTest + @WithClasses(ErroneousMapper4.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Can't map property \"UnmappableClass source\" to \"String property\". " + + "Consider to declare/implement a mapping method: \"String map(UnmappableClass value)\".") + } + ) + public void testUnmappableParameterAssignment() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/Source.java new file mode 100644 index 0000000000..10d43623e5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/Source.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +public class Source { + + private UnmappableClass source; + private UnmappableClass nameBasedSource; + + public UnmappableClass getSource() { + return source; + } + + public void setSource(UnmappableClass source) { + this.source = source; + } + + public UnmappableClass getNameBasedSource() { + return nameBasedSource; + } + + public void setNameBasedSource(UnmappableClass nameBasedSource) { + this.nameBasedSource = nameBasedSource; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/Target.java new file mode 100644 index 0000000000..c811a30019 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/Target.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +public class Target { + + private String property; + private String nameBasedSource; + private UnmappableClass constant; + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + + public String getNameBasedSource() { + return nameBasedSource; + } + + public void setNameBasedSource(String nameBasedSource) { + this.nameBasedSource = nameBasedSource; + } + + public UnmappableClass getConstant() { + return constant; + } + + public void setConstant(UnmappableClass constant) { + this.constant = constant; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/UnmappableClass.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/UnmappableClass.java new file mode 100644 index 0000000000..6f1a796777 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/propertymapping/UnmappableClass.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.propertymapping; + +public class UnmappableClass { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/AbstractMapper.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/AbstractMapper.java new file mode 100644 index 0000000000..5155ac386c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/AbstractMapper.java @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +public interface AbstractMapper { + + TARGET map(SOURCE source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousMapper1.java new file mode 100644 index 0000000000..95a0784934 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousMapper1.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +import org.mapstruct.Mapper; + +@Mapper +public interface ErroneousMapper1 extends AbstractMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousMapper2.java new file mode 100644 index 0000000000..b75f1a0e73 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousMapper2.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +import org.mapstruct.Mapper; + +@Mapper +public interface ErroneousMapper2 extends AbstractMapper { + @Override + Target map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousPropertyMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousPropertyMappingTest.java new file mode 100644 index 0000000000..147f1d6929 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/ErroneousPropertyMappingTest.java @@ -0,0 +1,51 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +@IssueKey( "598" ) +@WithClasses( { Source.class, Target.class, UnmappableClass.class, AbstractMapper.class } ) +public class ErroneousPropertyMappingTest { + + @ProcessorTest + @WithClasses( ErroneousMapper1.class ) + @IssueKey( "598" ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapper1.class, + line = 11, + messageRegExp = "Can't map property \"UnmappableClass property\" to \"String property\"\\. " + + "Consider to declare/implement a mapping method: \"String map\\(UnmappableClass value\\)\"\\. " + + "Occured at 'TARGET map\\(SOURCE source\\)' in 'AbstractMapper'\\.") + } + ) + public void testUnmappableSourcePropertyInSuperclass() { + } + + @ProcessorTest + @WithClasses( ErroneousMapper2.class ) + @IssueKey( "598" ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = ErroneousMapper2.class, + line = 13, + message = "Can't map property \"UnmappableClass property\" to \"String property\". " + + "Consider to declare/implement a mapping method: \"String map(UnmappableClass value)\".") } ) + public void testMethodOverride() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/Source.java new file mode 100644 index 0000000000..383eb1dbe6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/Source.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +public class Source { + + private UnmappableClass property; + + public UnmappableClass getProperty() { + return property; + } + + public void setProperty(UnmappableClass property) { + this.property = property; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/Target.java new file mode 100644 index 0000000000..f647ad7afa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/Target.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +public class Target { + + private String property; + + public String getProperty() { + return property; + } + + public void setProperty(String property) { + this.property = property; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/UnmappableClass.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/UnmappableClass.java new file mode 100644 index 0000000000..af239fb046 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/supermappingwithsubclassmapper/UnmappableClass.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.erroneous.supermappingwithsubclassmapper; + +public class UnmappableClass { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMapper.java index 48facfab40..c57c3a1262 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.typemismatch; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMappingsTest.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMappingsTest.java index 1b3e9cee6e..a045d16dfa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMappingsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/ErroneousMappingsTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.typemismatch; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Tests failures expected for unmappable attributes. @@ -35,37 +20,36 @@ * @author Gunnar Morling */ @WithClasses({ ErroneousMapper.class, Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ErroneousMappingsTest { - @Test + @ProcessorTest @IssueKey("6") @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 27, - messageRegExp = "Can't map property \"boolean foo\" to \"int foo\". Consider to declare/implement a " - + "mapping method: \"int map\\(boolean value\\)\"."), + line = 14, + message = "Can't map property \"boolean foo\" to \"int foo\". Consider to declare/implement a " + + "mapping method: \"int map(boolean value)\"."), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \"int foo\" to \"boolean foo\". Consider to declare/implement a " - + "mapping method: \"boolean map\\(int value\\)\"."), + line = 16, + message = "Can't map property \"int foo\" to \"boolean foo\". Consider to declare/implement a " + + "mapping method: \"boolean map(int value)\"."), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 31, - messageRegExp = "Can't generate mapping method with primitive return type\\."), + line = 18, + message = "Can't generate mapping method with primitive return type."), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 33, - messageRegExp = "Can't generate mapping method with primitive parameter type\\."), + line = 20, + message = "Can't generate mapping method with primitive parameter type."), @Diagnostic(type = ErroneousMapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = - "Can't generate mapping method that has a parameter annotated with @TargetType\\.") + line = 22, + message = + "Can't generate mapping method that has a parameter annotated with @TargetType.") } ) public void shouldFailToGenerateMappings() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Source.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Source.java index 28fb0ec0e8..9a0148c772 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.typemismatch; diff --git a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Target.java b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Target.java index ae70028e4f..5d967b5790 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/erroneous/typemismatch/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.erroneous.typemismatch; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTest.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTest.java index fdd3d45253..212893052a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTest.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; @@ -24,13 +11,13 @@ import java.util.List; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.exceptions.imports.TestException1; import org.mapstruct.ap.test.exceptions.imports.TestExceptionBase; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * @@ -45,105 +32,115 @@ TestExceptionBase.class, TestException1.class, TestException2.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class ExceptionTest { - @Test( expected = RuntimeException.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowRuntimeInBeanMapping() throws TestException2, ParseException { Source source = new Source(); source.setSize( 1 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.sourceToTarget( source ); + assertThatThrownBy( () -> sourceTargetMapper.sourceToTarget( source ) ) + .isInstanceOf( RuntimeException.class ); } - @Test( expected = TestException2.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowTestException2InBeanMapping() throws TestException2, ParseException { Source source = new Source(); source.setSize( 2 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.sourceToTarget( source ); + assertThatThrownBy( () -> sourceTargetMapper.sourceToTarget( source ) ) + .isInstanceOf( TestException2.class ); } - @Test( expected = ParseException.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowTestParseExceptionInBeanMappingDueToTypeConverion() throws TestException2, ParseException { Source source = new Source(); source.setDate( "nonsense" ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.sourceToTarget( source ); + assertThatThrownBy( () -> sourceTargetMapper.sourceToTarget( source ) ) + .isInstanceOf( ParseException.class ); } - @Test( expected = RuntimeException.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowRuntimeInIterableMapping() throws TestException2 { - List source = new ArrayList(); + List source = new ArrayList<>(); source.add( 1 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.integerListToLongList( source ); + assertThatThrownBy( () -> sourceTargetMapper.integerListToLongList( source ) ) + .isInstanceOf( RuntimeException.class ); } - @Test( expected = TestException2.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowTestException2InIterableMapping() throws TestException2 { - List source = new ArrayList(); + List source = new ArrayList<>(); source.add( 2 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.integerListToLongList( source ); + assertThatThrownBy( () -> sourceTargetMapper.integerListToLongList( source ) ) + .isInstanceOf( TestException2.class ); } - @Test( expected = RuntimeException.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowRuntimeInMapKeyMapping() throws TestException2 { - Map source = new HashMap(); + Map source = new HashMap<>(); source.put( 1, "test" ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.integerKeyMapToLongKeyMap( source ); + assertThatThrownBy( () -> sourceTargetMapper.integerKeyMapToLongKeyMap( source ) ) + .isInstanceOf( RuntimeException.class ); } - @Test( expected = TestException2.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowTestException2InMapKeyMapping() throws TestException2 { - Map source = new HashMap(); + Map source = new HashMap<>(); source.put( 2, "test" ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.integerKeyMapToLongKeyMap( source ); + assertThatThrownBy( () -> sourceTargetMapper.integerKeyMapToLongKeyMap( source ) ) + .isInstanceOf( TestException2.class ); } - @Test( expected = RuntimeException.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowRuntimeInMapValueMapping() throws TestException2 { - Map source = new HashMap(); + Map source = new HashMap<>(); source.put( "test", 1 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.integerValueMapToLongValueMap( source ); + assertThatThrownBy( () -> sourceTargetMapper.integerValueMapToLongValueMap( source ) ) + .isInstanceOf( RuntimeException.class ); } - @Test( expected = TestException2.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowTestException2InMapValueMapping() throws TestException2 { - Map source = new HashMap(); + Map source = new HashMap<>(); source.put( "test", 2 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.integerValueMapToLongValueMap( source ); + assertThatThrownBy( () -> sourceTargetMapper.integerValueMapToLongValueMap( source ) ) + .isInstanceOf( TestException2.class ); } - @Test( expected = RuntimeException.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowRuntimeInBeanMappingViaBaseException() throws TestExceptionBase { Source source = new Source(); source.setSize( 1 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.sourceToTargetViaBaseException( source ); + assertThatThrownBy( () -> sourceTargetMapper.sourceToTargetViaBaseException( source ) ) + .isInstanceOf( RuntimeException.class ); } - @Test( expected = TestException2.class ) + @ProcessorTest @IssueKey( "198" ) public void shouldThrowTestException2InBeanMappingViaBaseException() throws TestExceptionBase { Source source = new Source(); source.setSize( 2 ); SourceTargetMapper sourceTargetMapper = SourceTargetMapper.INSTANCE; - sourceTargetMapper.sourceToTargetViaBaseException( source ); + assertThatThrownBy( () -> sourceTargetMapper.sourceToTargetViaBaseException( source ) ) + .isInstanceOf( TestException2.class ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestDecorator.java index 76935d5c60..8c8b328c97 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestMapper.java index 9c285713f6..13d0d1f5cf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/ExceptionTestMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; @@ -33,6 +20,6 @@ public Long toLong(Integer size) throws TestException1, TestException2 { else if ( size == 2 ) { throw new TestException2(); } - return new Long(size); + return Long.valueOf( size ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/Source.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/Source.java index d0c71df15b..52a96d54ea 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/SourceTargetMapper.java index 58a851d329..0e5bb43f02 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/Target.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/Target.java index d56a25b5e1..ff6cd1aa25 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/TestException2.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/TestException2.java index 1b9ff31b96..2e41f8d193 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/TestException2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/TestException2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestException1.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestException1.java index b3a1d6b9d0..6129110307 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestException1.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestException1.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestExceptionBase.java b/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestExceptionBase.java index bdf4a9450f..b55e297452 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestExceptionBase.java +++ b/processor/src/test/java/org/mapstruct/ap/test/exceptions/imports/TestExceptionBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.exceptions.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar1.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar1.java index 0463ce50a8..517a55c81f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar1.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar1.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar2.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar2.java index 64164a5bca..4859d595c0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar3.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar3.java index e493f9da38..6b7eebf6e9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar3.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar3.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar4.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar4.java index fc3e7cc22f..05b4c695af 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Bar4.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Bar4.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomList.java b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomList.java index 9ecb0eb64b..805937a450 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomList.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomList.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomListImpl.java b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomListImpl.java index 156fa870cd..887c25416f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomListImpl.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomListImpl.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMap.java b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMap.java index 748c721a83..1dcb8d2951 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMap.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMap.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMapImpl.java b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMapImpl.java index 54d716c77d..a9e3cd84b3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMapImpl.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/CustomMapImpl.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryCreatable.java b/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryCreatable.java index 6a28e077b7..b5b77f93d5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryCreatable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryCreatable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryTest.java index 327bc16ad3..58cb0a1fcf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/FactoryTest.java @@ -1,32 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.factories.a.BarFactory; import org.mapstruct.ap.test.factories.targettype.Bar9Base; import org.mapstruct.ap.test.factories.targettype.Bar9Child; @@ -34,8 +17,10 @@ import org.mapstruct.ap.test.factories.targettype.Foo9Base; import org.mapstruct.ap.test.factories.targettype.Foo9Child; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Sjaak Derksen @@ -46,9 +31,8 @@ org.mapstruct.ap.test.factories.b.BarFactory.class, org.mapstruct.ap.test.factories.c.BarFactory.class, Bar9Factory.class, Source.class, SourceTargetMapperAndBar2Factory.class, Target.class, CustomList.class, CustomListImpl.class, CustomMap.class, CustomMapImpl.class, FactoryCreatable.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class FactoryTest { - @Test + @ProcessorTest public void shouldUseThreeFactoryMethods() { Target target = SourceTargetMapperAndBar2Factory.INSTANCE.sourceToTarget( createSource() ); @@ -97,17 +81,17 @@ private Source createSource() { foo4.setProp( "foo4" ); source.setProp4( foo4 ); - List fooList = new ArrayList(); + List fooList = new ArrayList<>(); fooList.add( "fooListEntry" ); source.setPropList( fooList ); - Map fooMap = new HashMap(); + Map fooMap = new HashMap<>(); fooMap.put( "key", "fooValue" ); source.setPropMap( fooMap ); return source; } - @Test + @ProcessorTest @IssueKey( "136" ) @WithClasses( { GenericFactory.class, SourceTargetMapperWithGenericFactory.class } ) public void shouldUseGenericFactory() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo1.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo1.java index 817e65bb92..ce75e17d7e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo1.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo1.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo2.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo2.java index d46d7088b6..37c9d44a00 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo3.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo3.java index 7955f89d75..7430e8bd66 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo3.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo3.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo4.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo4.java index ba741b9e54..87433ad408 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Foo4.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Foo4.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/GenericFactory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/GenericFactory.java index 601ed9da77..b0822e683c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/GenericFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/GenericFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Source.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Source.java index a3b527e6f1..06db859fea 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperAndBar2Factory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperAndBar2Factory.java index 80da7faa8e..568b9abf2a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperAndBar2Factory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperAndBar2Factory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; @@ -53,10 +40,10 @@ public Bar2 createBar2() { } public CustomList createCustomList() { - return new CustomListImpl( "CUSTOMLIST" ); + return new CustomListImpl<>( "CUSTOMLIST" ); } public CustomMap createCustomMap() { - return new CustomMapImpl( "CUSTOMMAP" ); + return new CustomMapImpl<>( "CUSTOMMAP" ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperWithGenericFactory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperWithGenericFactory.java index aeeca0f3b8..5367453157 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperWithGenericFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/SourceTargetMapperWithGenericFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/Target.java b/processor/src/test/java/org/mapstruct/ap/test/factories/Target.java index e5cfea36f3..46724cd07a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/a/BarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/a/BarFactory.java index cdc877735d..39665a432c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/a/BarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/a/BarFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.a; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5.java index 3d06954967..6f75afd991 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5Factory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5Factory.java index 68e3df1c9d..704e99bc33 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5Factory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar5Factory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6.java index 7cd6c93d33..dfce7ab2e9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6Factory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6Factory.java index f3b035168c..9695af8461 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6Factory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar6Factory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7.java index d1e69b2db6..37602cd0aa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7Factory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7Factory.java index 055676692c..fa90aa2a07 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7Factory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Bar7Factory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5A.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5A.java index bd7de6cd39..cf8f337279 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5A.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5A.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5B.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5B.java index c78bf18a1b..8c860277f9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5B.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo5B.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6A.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6A.java index a87fff17fb..cb4dd30f9c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6A.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6A.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6B.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6B.java index eff9a25a7d..783a7ec5ca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6B.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo6B.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7A.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7A.java index 928967e70d..56d3707680 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7A.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7A.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7B.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7B.java index 6e0d620aa4..1670a587c5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7B.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/Foo7B.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssigmentFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssigmentFactoryTest.java index ea7a4aeb68..41140a00a4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssigmentFactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssigmentFactoryTest.java @@ -1,39 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Remo Meier */ @WithClasses( { Bar5.class, Foo5A.class, Foo5B.class, Bar6.class, Foo6A.class, Foo6B.class, Bar7.class, Foo7A.class, Foo7B.class, Bar5Factory.class, Bar6Factory.class, Bar7Factory.class, ParameterAssignmentFactoryTestMapper.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class ParameterAssigmentFactoryTest { - @Test + @ProcessorTest public void shouldUseFactoryMethodWithMultipleParams() { Foo5A foo5a = new Foo5A(); foo5a.setPropB( "foo5a" ); @@ -51,7 +35,7 @@ public void shouldUseFactoryMethodWithMultipleParams() { assertThat( bar5.getSomeTypeProp1() ).isEqualTo( "foo5b" ); } - @Test + @ProcessorTest public void shouldUseFactoryMethodWithFirstParamsOfMappingMethod() { Foo6A foo6a = new Foo6A(); foo6a.setPropB( "foo6a" ); @@ -67,7 +51,7 @@ public void shouldUseFactoryMethodWithFirstParamsOfMappingMethod() { assertThat( bar6.getSomeTypeProp0() ).isEqualTo( "FOO6A" ); } - @Test + @ProcessorTest public void shouldUseFactoryMethodWithSecondParamsOfMappingMethod() { Foo7A foo7a = new Foo7A(); foo7a.setPropB( "foo7a" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssignmentFactoryTestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssignmentFactoryTestMapper.java index e45198f47a..d6d0bc2791 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssignmentFactoryTestMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/assignment/ParameterAssignmentFactoryTestMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.assignment; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/b/BarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/b/BarFactory.java index 2584db5229..0b05a663be 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/b/BarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/b/BarFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.b; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/c/BarFactory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/c/BarFactory.java index 9793b5a53e..bf7facbbd5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/c/BarFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/c/BarFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.c; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10.java b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10.java index f3f0074e9b..0fdae17e62 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.qualified; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10Factory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10Factory.java index 271d28d2b8..bd18fed865 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10Factory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Bar10Factory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.qualified; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Foo10.java b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Foo10.java index 5067ddfc29..e78332cdb4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Foo10.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/Foo10.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.qualified; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTest.java index 93d117ce0f..ac84e555d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTest.java @@ -1,38 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.qualified; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Remo Meier */ @WithClasses( { Foo10.class, Bar10.class, TestQualifier.class, Bar10Factory.class, QualifiedFactoryTestMapper.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class QualifiedFactoryTest { - @Test + @ProcessorTest public void shouldUseFactoryWithoutQualifier() { Foo10 foo10 = new Foo10(); foo10.setProp( "foo10" ); @@ -44,7 +28,7 @@ public void shouldUseFactoryWithoutQualifier() { assertThat( bar10.getSomeTypeProp() ).isEqualTo( "foo10" ); } - @Test + @ProcessorTest public void shouldUseFactoryWithQualifier() { Foo10 foo10 = new Foo10(); foo10.setProp( "foo10" ); @@ -56,7 +40,7 @@ public void shouldUseFactoryWithQualifier() { assertThat( bar10.getSomeTypeProp() ).isEqualTo( "foo10" ); } - @Test + @ProcessorTest public void shouldUseFactoryWithQualifierName() { Foo10 foo10 = new Foo10(); foo10.setProp( "foo10" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTestMapper.java index d697f84798..467a14d800 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTestMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/QualifiedFactoryTestMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.qualified; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/TestQualifier.java b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/TestQualifier.java index 6d5a9bd0cd..704c8c73fd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/TestQualifier.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/qualified/TestQualifier.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.qualified; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Base.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Base.java index 229f1782ec..7ee28ba3d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Base.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Base.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Child.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Child.java index 4d397dfa96..f5e814d094 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Child.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Child.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Factory.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Factory.java index e25b9e98b2..631d0d6f09 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Factory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Bar9Factory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Base.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Base.java index ceacf3ae79..d2ac9a1c29 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Base.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Base.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Child.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Child.java index cd540eaf07..d848ee6ca1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Child.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/Foo9Child.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/ProductTypeFactoryTest.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/ProductTypeFactoryTest.java index 4e61915d19..ce140ee93c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/ProductTypeFactoryTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/ProductTypeFactoryTest.java @@ -1,39 +1,23 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Remo Meier */ @WithClasses( { Foo9Base.class, Foo9Child.class, Bar9Base.class, Bar9Child.class, Bar9Factory.class, TargetTypeFactoryTestMapper.class } ) -@RunWith( AnnotationProcessorTestRunner.class ) public class ProductTypeFactoryTest { - @Test + @ProcessorTest public void shouldUseFactoryTwoCreateBaseClassDueToTargetType() { Foo9Base foo9 = new Foo9Base(); foo9.setProp( "foo9" ); @@ -45,7 +29,7 @@ public void shouldUseFactoryTwoCreateBaseClassDueToTargetType() { assertThat( bar9.getSomeTypeProp() ).isEqualTo( "FOO9" ); } - @Test + @ProcessorTest public void shouldUseFactoryTwoCreateChildClassDueToTargetType() { Foo9Child foo9 = new Foo9Child(); foo9.setProp( "foo9" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/TargetTypeFactoryTestMapper.java b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/TargetTypeFactoryTestMapper.java index f549e47779..5f37342ada 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/TargetTypeFactoryTestMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/factories/targettype/TargetTypeFactoryTestMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.factories.targettype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/fields/FieldsMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/fields/FieldsMappingTest.java index df6fccd51f..8e594969fc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/fields/FieldsMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/fields/FieldsMappingTest.java @@ -1,48 +1,32 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.fields; -import static org.assertj.core.api.Assertions.assertThat; - import org.assertj.core.util.Lists; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey( "557" ) @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) public class FieldsMappingTest { - @Test - public void shouldMapSourceToTarget() throws Exception { + @ProcessorTest + public void shouldMapSourceToTarget() { Source source = new Source(); source.normalInt = 4; source.normalList = Lists.newArrayList( 10, 11, 12 ); source.fieldOnlyWithGetter = 20; - Target target = SourceTargetMapper.INSTANCE.toSource( source ); + Target target = SourceTargetMapper.INSTANCE.toTarget( source ); assertThat( target ).isNotNull(); assertThat( target.finalInt ).isEqualTo( "10" ); @@ -54,8 +38,8 @@ public void shouldMapSourceToTarget() throws Exception { assertThat( target.fieldWithMethods ).isEqualTo( "4111" ); } - @Test - public void shouldMapTargetToSource() throws Exception { + @ProcessorTest + public void shouldMapTargetToSource() { Target target = new Target(); target.finalInt = "40"; target.normalInt = "4"; diff --git a/processor/src/test/java/org/mapstruct/ap/test/fields/Source.java b/processor/src/test/java/org/mapstruct/ap/test/fields/Source.java index e9dbfc134f..9e8137aee8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/fields/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/fields/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.fields; @@ -35,7 +22,7 @@ public class Source { public Integer fieldOnlyWithGetter; // CHECKSTYLE:ON - private final List privateFinalList = new ArrayList( Arrays.asList( 3, 4, 5 ) ); + private final List privateFinalList = new ArrayList<>( Arrays.asList( 3, 4, 5 ) ); public List getPrivateFinalList() { return privateFinalList; diff --git a/processor/src/test/java/org/mapstruct/ap/test/fields/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/fields/SourceTargetMapper.java index 2f819681cf..0716c380be 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/fields/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/fields/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.fields; @@ -31,8 +18,8 @@ public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - @Mapping(source = "fieldOnlyWithGetter", target = "fieldWithMethods") - Target toSource(Source source); + @Mapping(target = "fieldWithMethods", source = "fieldOnlyWithGetter") + Target toTarget(Source source); @InheritInverseConfiguration Source toSource(Target target); diff --git a/processor/src/test/java/org/mapstruct/ap/test/fields/Target.java b/processor/src/test/java/org/mapstruct/ap/test/fields/Target.java index 871799a4de..51ef1f6c0d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/fields/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/fields/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.fields; diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/FromMapMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/FromMapMappingTest.java new file mode 100644 index 0000000000..bcb78d8dcc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/FromMapMappingTest.java @@ -0,0 +1,385 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.text.ParseException; +import java.time.LocalDate; +import java.time.Month; +import java.time.format.DateTimeParseException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.junit.jupiter.api.Nested; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.assertj.core.api.Assertions.entry; + +/** + * @author Christian Kosmowski + */ +@IssueKey("1075") +class FromMapMappingTest { + + @Nested + @WithClasses({ + StringMapToBeanMapper.class + }) + class StringMapToBeanTests { + + @ProcessorTest + void fromNullMap() { + assertThat( StringMapToBeanMapper.INSTANCE.fromMap( null ) ).isNull(); + } + + @ProcessorTest + void fromEmptyMap() { + StringMapToBeanMapper.Order order = StringMapToBeanMapper.INSTANCE.fromMap( Collections.emptyMap() ); + + assertThat( order ).isNotNull(); + assertThat( order.getName() ).isNull(); + assertThat( order.getPrice() ).isEqualTo( 0.0 ); + assertThat( order.getOrderDate() ).isNull(); + assertThat( order.getShipmentDate() ).isNull(); + } + + @ProcessorTest + void fromFullMap() { + Map map = new HashMap<>(); + map.put( "name", "Jacket" ); + map.put( "price", "25.5" ); + map.put( "shipmentDate", "2021-06-15" ); + StringMapToBeanMapper.Order order = StringMapToBeanMapper.INSTANCE.fromMap( map ); + + assertThat( order ).isNotNull(); + assertThat( order.getName() ).isEqualTo( "Jacket" ); + assertThat( order.getPrice() ).isEqualTo( 25.5 ); + assertThat( order.getOrderDate() ).isNull(); + assertThat( order.getShipmentDate() ).isEqualTo( LocalDate.of( 2021, Month.JUNE, 15 ) ); + } + + @ProcessorTest + void fromMapWithEmptyValuesForString() { + Map map = Collections.singletonMap( "name", "" ); + StringMapToBeanMapper.Order order = StringMapToBeanMapper.INSTANCE.fromMap( map ); + + assertThat( order ).isNotNull(); + assertThat( order.getName() ).isEqualTo( "" ); + assertThat( order.getPrice() ).isEqualTo( 0 ); + assertThat( order.getOrderDate() ).isNull(); + assertThat( order.getShipmentDate() ).isNull(); + } + + @ProcessorTest + void fromMapWithEmptyValuesForDouble() { + Map map = Collections.singletonMap( "price", "" ); + assertThatThrownBy( () -> StringMapToBeanMapper.INSTANCE.fromMap( map ) ) + .isInstanceOf( NumberFormatException.class ); + } + + @ProcessorTest + void fromMapWithEmptyValuesForDate() { + Map map = Collections.singletonMap( "orderDate", "" ); + assertThatThrownBy( () -> StringMapToBeanMapper.INSTANCE.fromMap( map ) ) + .isInstanceOf( RuntimeException.class ) + .getCause() + .isInstanceOf( ParseException.class ); + } + + @ProcessorTest + void fromMapWithEmptyValuesForLocalDate() { + Map map = Collections.singletonMap( "shipmentDate", "" ); + assertThatThrownBy( () -> StringMapToBeanMapper.INSTANCE.fromMap( map ) ) + .isInstanceOf( DateTimeParseException.class ); + } + } + + @Nested + @WithClasses({ + StringMapToBeanWithCustomPresenceCheckMapper.class + }) + class StringMapToBeanWithCustomPresenceCheckTests { + + @ProcessorTest + void fromFullMap() { + Map map = new HashMap<>(); + map.put( "name", "Jacket" ); + map.put( "price", "25.5" ); + map.put( "shipmentDate", "2021-06-15" ); + StringMapToBeanWithCustomPresenceCheckMapper.Order order = + StringMapToBeanWithCustomPresenceCheckMapper.INSTANCE.fromMap( map ); + + assertThat( order ).isNotNull(); + assertThat( order.getName() ).isEqualTo( "Jacket" ); + assertThat( order.getPrice() ).isEqualTo( 25.5 ); + assertThat( order.getOrderDate() ).isNull(); + assertThat( order.getShipmentDate() ).isEqualTo( LocalDate.of( 2021, Month.JUNE, 15 ) ); + } + + @ProcessorTest + void fromMapWithEmptyValuesForString() { + Map map = new HashMap<>(); + map.put( "name", "" ); + map.put( "price", "" ); + map.put( "orderDate", "" ); + map.put( "shipmentDate", "" ); + StringMapToBeanWithCustomPresenceCheckMapper.Order order = + StringMapToBeanWithCustomPresenceCheckMapper.INSTANCE.fromMap( map ); + + assertThat( order ).isNotNull(); + assertThat( order.getName() ).isNull(); + assertThat( order.getPrice() ).isEqualTo( 0 ); + assertThat( order.getOrderDate() ).isNull(); + assertThat( order.getShipmentDate() ).isNull(); + } + + } + + @ProcessorTest + @WithClasses(MapToBeanDefinedMapper.class) + void shouldMapWithDefinedMapping() { + Map sourceMap = new HashMap<>(); + sourceMap.put( "number", 44 ); + + MapToBeanDefinedMapper.Target target = MapToBeanDefinedMapper.INSTANCE.toTarget( sourceMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getNormalInt() ).isEqualTo( "44" ); + } + + @ProcessorTest + @WithClasses(MapToBeanImplicitMapper.class) + void shouldMapWithImpicitMapping() { + Map sourceMap = new HashMap<>(); + sourceMap.put( "name", "mapstruct" ); + + MapToBeanImplicitMapper.Target target = MapToBeanImplicitMapper.INSTANCE.toTarget( sourceMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "mapstruct" ); + } + + @ProcessorTest + @WithClasses(MapToBeanUpdateImplicitMapper.class) + void shouldMapToExistingTargetWithImplicitMapping() { + Map sourceMap = new HashMap<>(); + sourceMap.put( "rating", 5 ); + + MapToBeanUpdateImplicitMapper.Target existingTarget = new MapToBeanUpdateImplicitMapper.Target(); + existingTarget.setRating( 4 ); + existingTarget.setName( "mapstruct" ); + + MapToBeanUpdateImplicitMapper.Target target = MapToBeanUpdateImplicitMapper.INSTANCE + .toTarget( existingTarget, sourceMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "mapstruct" ); + assertThat( target.getRating() ).isEqualTo( 5 ); + } + + @ProcessorTest + @WithClasses(MapToBeanWithDefaultMapper.class) + void shouldMapWithDefaultValue() { + Map sourceMap = new HashMap<>(); + + MapToBeanWithDefaultMapper.Target target = MapToBeanWithDefaultMapper.INSTANCE + .toTarget( sourceMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getNormalInt() ).isEqualTo( "4711" ); + } + + @ProcessorTest + @WithClasses(MapToBeanUsingMappingMethodMapper.class) + void shouldMapUsingMappingMethod() { + Map sourceMap = new HashMap<>(); + sourceMap.put( "number", 23 ); + + MapToBeanUsingMappingMethodMapper.Target target = MapToBeanUsingMappingMethodMapper.INSTANCE + .toTarget( sourceMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getNormalInt() ).isEqualTo( "converted_23" ); + } + + @ProcessorTest + @WithClasses(MapToBeanFromMultipleSources.class) + void shouldMapFromMultipleSources() { + Map integers = new HashMap<>(); + integers.put( "number", 23 ); + + Map strings = new HashMap<>(); + strings.put( "string", "stringFromMap" ); + + MapToBeanFromMultipleSources.Source source = new MapToBeanFromMultipleSources.Source(); + + MapToBeanFromMultipleSources.Target target = MapToBeanFromMultipleSources.INSTANCE + .toTarget( integers, strings, source ); + + assertThat( target ).isNotNull(); + assertThat( target.getInteger() ).isEqualTo( 23 ); + assertThat( target.getString() ).isEqualTo( "stringFromMap" ); + assertThat( target.getStringFromBean() ).isEqualTo( "stringFromBean" ); + } + + @ProcessorTest + @WithClasses(MapToBeanFromMapAndNestedSource.class) + void shouldMapFromNestedSource() { + Map integers = new HashMap<>(); + integers.put( "number", 23 ); + + MapToBeanFromMapAndNestedSource.Source source = new MapToBeanFromMapAndNestedSource.Source(); + + MapToBeanFromMapAndNestedSource.Target target = MapToBeanFromMapAndNestedSource.INSTANCE + .toTarget( integers, source ); + + assertThat( target ).isNotNull(); + assertThat( target.getInteger() ).isEqualTo( 23 ); + assertThat( target.getStringFromNestedSource() ).isEqualTo( "nestedString" ); + } + + @ProcessorTest + @WithClasses(MapToBeanFromMapAndNestedMap.class) + void shouldMapFromNestedMap() { + + MapToBeanFromMapAndNestedMap.Source source = new MapToBeanFromMapAndNestedMap.Source(); + MapToBeanFromMapAndNestedMap.Target target = MapToBeanFromMapAndNestedMap.INSTANCE + .toTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getNestedTarget() ).isNotNull(); + assertThat( target.getNestedTarget().getStringFromNestedMap() ).isEqualTo( "valueFromNestedMap" ); + } + + @IssueKey("2553") + @ProcessorTest + @WithClasses(MapToBeanFromMapAndNestedMapWithDefinedMapping.class) + void shouldMapFromNestedMapWithDefinedMapping() { + + MapToBeanFromMapAndNestedMapWithDefinedMapping.Source source = + new MapToBeanFromMapAndNestedMapWithDefinedMapping.Source(); + MapToBeanFromMapAndNestedMapWithDefinedMapping.Target target = + MapToBeanFromMapAndNestedMapWithDefinedMapping.INSTANCE.toTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getNested() ).isEqualTo( "valueFromNestedMap" ); + } + + @ProcessorTest + @WithClasses(ObjectMapToBeanWithQualifierMapper.class) + void shouldUseObjectQualifiedMethod() { + Map vehicles = new HashMap<>(); + vehicles.put( "car", new ObjectMapToBeanWithQualifierMapper.Car( "Tesla" ) ); + + ObjectMapToBeanWithQualifierMapper.VehiclesDto dto = + ObjectMapToBeanWithQualifierMapper.INSTANCE.map( vehicles ); + + assertThat( dto.getCar() ).isNotNull(); + assertThat( dto.getCar() ).isInstanceOf( ObjectMapToBeanWithQualifierMapper.CarDto.class ); + assertThat( dto.getCar().getBrand() ).isEqualTo( "Tesla" ); + } + + @ProcessorTest + @WithClasses(MapToBeanTypeCheckMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + type = MapToBeanTypeCheckMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 21, + message = "Unmapped target property: \"value\"." + ), + @Diagnostic( + type = MapToBeanTypeCheckMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 21, + message = "The Map parameter \"source\" cannot be used for property mapping. " + + "It must be typed with Map but it was typed with Map." + ), + } + ) + void shouldWarnAboutWrongMapTypes() { + + Map upsideDownMap = new HashMap<>(); + upsideDownMap.put( 23, "number" ); + + MapToBeanTypeCheckMapper.Target target = MapToBeanTypeCheckMapper.INSTANCE + .toTarget( upsideDownMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + } + + @ProcessorTest + @WithClasses(MapToBeanRawMapMapper.class) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + type = MapToBeanRawMapMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 21, + message = "Unmapped target property: \"value\"." + ), + @Diagnostic( + type = MapToBeanRawMapMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 21, + message = "The Map parameter \"source\" cannot be used for property mapping. " + + "It must be typed with Map but it was raw." + ), + } + ) + void shouldWarnAboutRawMapTypes() { + + Map rawMap = new HashMap<>(); + rawMap.put( "value", "number" ); + + MapToBeanRawMapMapper.Target target = MapToBeanRawMapMapper.INSTANCE + .toTarget( rawMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + MapToBeanNonStringMapAsMultiSourceMapper.class + }) + void shouldNotWarnIfMappedIsUsedAsSourceParameter() { + MapToBeanNonStringMapAsMultiSourceMapper.Target target = MapToBeanNonStringMapAsMultiSourceMapper.INSTANCE + .toTarget( + new MapToBeanNonStringMapAsMultiSourceMapper.Source( "test" ), + Collections.singletonMap( 10, "value" ) + ); + + assertThat( target.getValue() ).isEqualTo( "test" ); + assertThat( target.getMap() ) + .containsOnly( entry( "10", "value" ) ); + } + + @ProcessorTest + @WithClasses(MapToBeanImplicitUnmappedSourcePolicyMapper.class) + void shouldNotReportUnmappedSourcePropertiesWithMap() { + Map sourceMap = new HashMap<>(); + sourceMap.put( "name", "mapstruct" ); + + MapToBeanImplicitUnmappedSourcePolicyMapper.Target target = + MapToBeanImplicitUnmappedSourcePolicyMapper.INSTANCE.toTarget( sourceMap ); + + assertThat( target ).isNotNull(); + assertThat( target.getName() ).isEqualTo( "mapstruct" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanDefinedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanDefinedMapper.java new file mode 100644 index 0000000000..eef8c285b3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanDefinedMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanDefinedMapper { + + MapToBeanDefinedMapper INSTANCE = Mappers.getMapper( MapToBeanDefinedMapper.class ); + + @Mapping(target = "normalInt", source = "number") + Target toTarget(Map source); + + class Target { + + private String normalInt; + + public String getNormalInt() { + return normalInt; + } + + public void setNormalInt(String normalInt) { + this.normalInt = normalInt; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedMap.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedMap.java new file mode 100644 index 0000000000..f1b21263a4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedMap.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanFromMapAndNestedMap { + + MapToBeanFromMapAndNestedMap INSTANCE = Mappers.getMapper( MapToBeanFromMapAndNestedMap.class ); + + Target toTarget(Source source); + + class Source { + + private Map nestedTarget = new HashMap<>( ); + + public Map getNestedTarget() { + return nestedTarget; + } + + public void setNestedTarget(Map nestedTarget) { + this.nestedTarget = nestedTarget; + } + + public Source() { + nestedTarget.put( "stringFromNestedMap", "valueFromNestedMap" ); + } + } + + class Target { + + private NestedTarget nestedTarget; + + public NestedTarget getNestedTarget() { + return nestedTarget; + } + + public void setNestedTarget(NestedTarget nestedTarget) { + this.nestedTarget = nestedTarget; + } + + } + + class NestedTarget { + private String stringFromNestedMap; + + public String getStringFromNestedMap() { + return stringFromNestedMap; + } + + public void setStringFromNestedMap(String stringFromNestedMap) { + this.stringFromNestedMap = stringFromNestedMap; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedMapWithDefinedMapping.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedMapWithDefinedMapping.java new file mode 100644 index 0000000000..2203836ea6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedMapWithDefinedMapping.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface MapToBeanFromMapAndNestedMapWithDefinedMapping { + + MapToBeanFromMapAndNestedMapWithDefinedMapping INSTANCE = Mappers.getMapper( + MapToBeanFromMapAndNestedMapWithDefinedMapping.class ); + + @Mapping(target = "nested", source = "nestedTarget.nested") + Target toTarget(Source source); + + class Source { + + private Map nestedTarget = new HashMap<>(); + + public Map getNestedTarget() { + return nestedTarget; + } + + public void setNestedTarget(Map nestedTarget) { + this.nestedTarget = nestedTarget; + } + + public Source() { + nestedTarget.put( "nested", "valueFromNestedMap" ); + } + } + + class Target { + + private String nested; + + public String getNested() { + return nested; + } + + public void setNested(String nested) { + this.nested = nested; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedSource.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedSource.java new file mode 100644 index 0000000000..c66080332e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMapAndNestedSource.java @@ -0,0 +1,79 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanFromMapAndNestedSource { + + MapToBeanFromMapAndNestedSource INSTANCE = Mappers.getMapper( MapToBeanFromMapAndNestedSource.class ); + + @Mapping(target = "integer", source = "integers.number") + @Mapping(target = "stringFromNestedSource", source = "source.nestedSource.nestedString") + Target toTarget(Map integers, Source source); + + class Source { + + private String stringFromBean = "stringFromBean"; + private NestedSource nestedSource = new NestedSource(); + + public String getStringFromBean() { + return stringFromBean; + } + + public void setStringFromBean(String stringFromBean) { + this.stringFromBean = stringFromBean; + } + + public NestedSource getNestedSource() { + return nestedSource; + } + + public void setNestedSource(NestedSource nestedSource) { + this.nestedSource = nestedSource; + } + + class NestedSource { + + private String nestedString = "nestedString"; + + public String getNestedString() { + return nestedString; + } + } + } + + class Target { + + private int integer; + private String stringFromNestedSource; + + public int getInteger() { + return integer; + } + + public void setInteger(int integer) { + this.integer = integer; + } + + public String getStringFromNestedSource() { + return stringFromNestedSource; + } + + public void setStringFromNestedSource(String stringFromNestedSource) { + this.stringFromNestedSource = stringFromNestedSource; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMultipleSources.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMultipleSources.java new file mode 100644 index 0000000000..c5c9b2e665 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanFromMultipleSources.java @@ -0,0 +1,70 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanFromMultipleSources { + + MapToBeanFromMultipleSources INSTANCE = Mappers.getMapper( MapToBeanFromMultipleSources.class ); + + @Mapping(target = "integer", source = "integers.number") + @Mapping(target = "string", source = "strings.string") + @Mapping(target = "stringFromBean", source = "bean.stringFromBean") + Target toTarget(Map integers, Map strings, Source bean); + + class Source { + private String stringFromBean = "stringFromBean"; + + public String getStringFromBean() { + return stringFromBean; + } + + public void setStringFromBean(String stringFromBean) { + this.stringFromBean = stringFromBean; + } + } + + class Target { + + private int integer; + private String string; + private String stringFromBean; + + public int getInteger() { + return integer; + } + + public void setInteger(int integer) { + this.integer = integer; + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + public String getStringFromBean() { + return stringFromBean; + } + + public void setStringFromBean(String stringFromBean) { + this.stringFromBean = stringFromBean; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanImplicitMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanImplicitMapper.java new file mode 100644 index 0000000000..ca4b7a3d21 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanImplicitMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanImplicitMapper { + + MapToBeanImplicitMapper INSTANCE = Mappers.getMapper( MapToBeanImplicitMapper.class ); + + Target toTarget(Map source); + + class Target { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanImplicitUnmappedSourcePolicyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanImplicitUnmappedSourcePolicyMapper.java new file mode 100644 index 0000000000..2c72dc7b70 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanImplicitUnmappedSourcePolicyMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface MapToBeanImplicitUnmappedSourcePolicyMapper { + + MapToBeanImplicitUnmappedSourcePolicyMapper INSTANCE = + Mappers.getMapper( MapToBeanImplicitUnmappedSourcePolicyMapper.class ); + + Target toTarget(Map source); + + class Target { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanNonStringMapAsMultiSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanNonStringMapAsMultiSourceMapper.java new file mode 100644 index 0000000000..2606a9a037 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanNonStringMapAsMultiSourceMapper.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanNonStringMapAsMultiSourceMapper { + + MapToBeanNonStringMapAsMultiSourceMapper INSTANCE = + Mappers.getMapper( MapToBeanNonStringMapAsMultiSourceMapper.class ); + + Target toTarget(Source source, Map map); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + + private final String value; + private final Map map; + + public Target(String value, Map map) { + this.value = value; + this.map = map; + } + + public String getValue() { + return value; + } + + public Map getMap() { + return map; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanRawMapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanRawMapMapper.java new file mode 100644 index 0000000000..40215ab183 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanRawMapMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanRawMapMapper { + + MapToBeanRawMapMapper INSTANCE = Mappers.getMapper( MapToBeanRawMapMapper.class ); + + Target toTarget(Map source); + + class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanTypeCheckMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanTypeCheckMapper.java new file mode 100644 index 0000000000..346c153d71 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanTypeCheckMapper.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanTypeCheckMapper { + + MapToBeanTypeCheckMapper INSTANCE = Mappers.getMapper( MapToBeanTypeCheckMapper.class ); + + Target toTarget(Map source); + + class Target { + + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanUpdateImplicitMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanUpdateImplicitMapper.java new file mode 100644 index 0000000000..82fe906bfe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanUpdateImplicitMapper.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface MapToBeanUpdateImplicitMapper { + + MapToBeanUpdateImplicitMapper INSTANCE = Mappers.getMapper( MapToBeanUpdateImplicitMapper.class ); + + Target toTarget(@MappingTarget Target target, Map source); + + class Target { + + private String name; + private Integer rating; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getRating() { + return rating; + } + + public void setRating(Integer rating) { + this.rating = rating; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanUsingMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanUsingMappingMethodMapper.java new file mode 100644 index 0000000000..225ca00adc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanUsingMappingMethodMapper.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanUsingMappingMethodMapper { + + MapToBeanUsingMappingMethodMapper INSTANCE = Mappers.getMapper( MapToBeanUsingMappingMethodMapper.class ); + + @Mapping(target = "normalInt", source = "source.number") + Target toTarget(Map source); + + default String mapIntegerToString( Integer input ) { + return "converted_" + input; + } + + class Target { + + private String normalInt; + + public String getNormalInt() { + return normalInt; + } + + public void setNormalInt(String normalInt) { + this.normalInt = normalInt; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanWithDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanWithDefaultMapper.java new file mode 100644 index 0000000000..104d34bd0a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/MapToBeanWithDefaultMapper.java @@ -0,0 +1,38 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Christian Kosmowski + */ +@Mapper +public interface MapToBeanWithDefaultMapper { + + MapToBeanWithDefaultMapper INSTANCE = Mappers.getMapper( MapToBeanWithDefaultMapper.class ); + + @Mapping(target = "normalInt", source = "number", defaultValue = "4711") + Target toTarget(Map source); + + class Target { + + private String normalInt; + + public String getNormalInt() { + return normalInt; + } + + public void setNormalInt(String normalInt) { + this.normalInt = normalInt; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/ObjectMapToBeanWithQualifierMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/ObjectMapToBeanWithQualifierMapper.java new file mode 100644 index 0000000000..54ddb0e42a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/ObjectMapToBeanWithQualifierMapper.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.frommap; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface ObjectMapToBeanWithQualifierMapper { + + ObjectMapToBeanWithQualifierMapper INSTANCE = Mappers.getMapper( ObjectMapToBeanWithQualifierMapper.class ); + + @Mapping( target = "car", qualifiedByName = "objectToCar") + VehiclesDto map(Map vehicles); + + @Named("objectToCar") + default CarDto objectToCar(Object object) { + CarDto car = new CarDto(); + + if ( object instanceof Car ) { + car.setBrand( ( (Car) object ).brand ); + } + + return car; + } + + class VehiclesDto { + + private VehicleDto car; + + public VehicleDto getCar() { + return car; + } + + public void setCar(VehicleDto car) { + this.car = car; + } + } + + class VehicleDto { + private String brand; + + public String getBrand() { + return brand; + } + + public void setBrand(String brand) { + this.brand = brand; + } + } + + class CarDto extends VehicleDto { + + } + + class Car { + + private final String brand; + + public Car(String brand) { + this.brand = brand; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/StringMapToBeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/StringMapToBeanMapper.java new file mode 100644 index 0000000000..95b0f72597 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/StringMapToBeanMapper.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.frommap; + +import java.time.LocalDate; +import java.util.Date; +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface StringMapToBeanMapper { + StringMapToBeanMapper INSTANCE = Mappers.getMapper( StringMapToBeanMapper.class ); + + Order fromMap(Map map); + + class Order { + private String name; + private double price; + private Date orderDate; + private LocalDate shipmentDate; + + public Order() { + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return this.price; + } + + public void setPrice(double price) { + this.price = price; + } + + public Date getOrderDate() { + return this.orderDate; + } + + public void setOrderDate(Date orderDate) { + this.orderDate = orderDate; + } + + public LocalDate getShipmentDate() { + return this.shipmentDate; + } + + public void setShipmentDate(LocalDate shipmentDate) { + this.shipmentDate = shipmentDate; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/frommap/StringMapToBeanWithCustomPresenceCheckMapper.java b/processor/src/test/java/org/mapstruct/ap/test/frommap/StringMapToBeanWithCustomPresenceCheckMapper.java new file mode 100644 index 0000000000..62c105599f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/frommap/StringMapToBeanWithCustomPresenceCheckMapper.java @@ -0,0 +1,74 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ + +package org.mapstruct.ap.test.frommap; + +import java.time.LocalDate; +import java.util.Date; +import java.util.Map; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface StringMapToBeanWithCustomPresenceCheckMapper { + StringMapToBeanWithCustomPresenceCheckMapper INSTANCE = + Mappers.getMapper( StringMapToBeanWithCustomPresenceCheckMapper.class ); + + Order fromMap(Map map); + + @Condition + default boolean isNotEmpty(String value) { + return value != null && !value.isEmpty(); + } + + class Order { + private String name; + private double price; + private Date orderDate; + private LocalDate shipmentDate; + + public Order() { + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public double getPrice() { + return this.price; + } + + public void setPrice(double price) { + this.price = price; + } + + public Date getOrderDate() { + return this.orderDate; + } + + public void setOrderDate(Date orderDate) { + this.orderDate = orderDate; + } + + public LocalDate getShipmentDate() { + return this.shipmentDate; + } + + public void setShipmentDate(LocalDate shipmentDate) { + this.shipmentDate = shipmentDate; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/gem/ConstantTest.java b/processor/src/test/java/org/mapstruct/ap/test/gem/ConstantTest.java new file mode 100644 index 0000000000..25489a5b6b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/gem/ConstantTest.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.gem; + +import org.junit.jupiter.api.Test; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.internal.gem.MappingConstantsGem; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test constants values + * + * @author Sjaak Derksen + */ +public class ConstantTest { + + @Test + public void constantsShouldBeEqual() { + assertThat( MappingConstants.ANY_REMAINING ).isEqualTo( MappingConstantsGem.ANY_REMAINING ); + assertThat( MappingConstants.ANY_UNMAPPED ).isEqualTo( MappingConstantsGem.ANY_UNMAPPED ); + assertThat( MappingConstants.NULL ).isEqualTo( MappingConstantsGem.NULL ); + assertThat( MappingConstants.THROW_EXCEPTION ).isEqualTo( MappingConstantsGem.THROW_EXCEPTION ); + assertThat( MappingConstants.SUFFIX_TRANSFORMATION ).isEqualTo( MappingConstantsGem.SUFFIX_TRANSFORMATION ); + assertThat( MappingConstants.STRIP_SUFFIX_TRANSFORMATION ) + .isEqualTo( MappingConstantsGem.STRIP_SUFFIX_TRANSFORMATION ); + assertThat( MappingConstants.PREFIX_TRANSFORMATION ).isEqualTo( MappingConstantsGem.PREFIX_TRANSFORMATION ); + assertThat( MappingConstants.STRIP_PREFIX_TRANSFORMATION ) + .isEqualTo( MappingConstantsGem.STRIP_PREFIX_TRANSFORMATION ); + assertThat( MappingConstants.CASE_TRANSFORMATION ).isEqualTo( MappingConstantsGem.CASE_TRANSFORMATION ); + } + + @Test + public void componentModelConstantsShouldBeEqual() { + assertThat( MappingConstants.ComponentModel.DEFAULT ) + .isEqualTo( MappingConstantsGem.ComponentModelGem.DEFAULT ); + assertThat( MappingConstants.ComponentModel.CDI ).isEqualTo( MappingConstantsGem.ComponentModelGem.CDI ); + assertThat( MappingConstants.ComponentModel.SPRING ).isEqualTo( MappingConstantsGem.ComponentModelGem.SPRING ); + assertThat( MappingConstants.ComponentModel.JSR330 ).isEqualTo( MappingConstantsGem.ComponentModelGem.JSR330 ); + assertThat( MappingConstants.ComponentModel.JAKARTA ) + .isEqualTo( MappingConstantsGem.ComponentModelGem.JAKARTA ); + assertThat( MappingConstants.ComponentModel.JAKARTA_CDI ) + .isEqualTo( MappingConstantsGem.ComponentModelGem.JAKARTA_CDI ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/gem/EnumGemsTest.java b/processor/src/test/java/org/mapstruct/ap/test/gem/EnumGemsTest.java new file mode 100644 index 0000000000..57c2099b8b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/gem/EnumGemsTest.java @@ -0,0 +1,91 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.gem; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; +import org.mapstruct.ClassAccessibility; +import org.mapstruct.CollectionMappingStrategy; +import org.mapstruct.ConditionStrategy; +import org.mapstruct.InjectionStrategy; +import org.mapstruct.MappingInheritanceStrategy; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.internal.gem.ClassAccessibilityGem; +import org.mapstruct.ap.internal.gem.CollectionMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ConditionStrategyGem; +import org.mapstruct.ap.internal.gem.InjectionStrategyGem; +import org.mapstruct.ap.internal.gem.MappingInheritanceStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueCheckStrategyGem; +import org.mapstruct.ap.internal.gem.NullValueMappingStrategyGem; +import org.mapstruct.ap.internal.gem.ReportingPolicyGem; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for manually created gems on enumeration types + * + * @author Andreas Gudian + */ +public class EnumGemsTest { + @Test + public void collectionMappingStrategyGemIsCorrect() { + assertThat( namesOf( CollectionMappingStrategy.values() ) ).isEqualTo( + namesOf( CollectionMappingStrategyGem.values() ) ); + } + + @Test + public void mappingInheritanceStrategyGemIsCorrect() { + assertThat( namesOf( MappingInheritanceStrategy.values() ) ).isEqualTo( + namesOf( MappingInheritanceStrategyGem.values() ) ); + } + + @Test + public void nullValueCheckStrategyGemIsCorrect() { + assertThat( namesOf( NullValueCheckStrategy.values() ) ).isEqualTo( + namesOf( NullValueCheckStrategyGem.values() ) ); + } + + @Test + public void nullValueMappingStrategyGemIsCorrect() { + assertThat( namesOf( NullValueMappingStrategy.values() ) ).isEqualTo( + namesOf( NullValueMappingStrategyGem.values() ) ); + } + + @Test + public void reportingPolicyGemIsCorrect() { + assertThat( namesOf( ReportingPolicy.values() ) ).isEqualTo( + namesOf( ReportingPolicyGem.values() ) ); + } + + @Test + public void injectionStrategyGemIsCorrect() { + assertThat( namesOf( InjectionStrategy.values() ) ).isEqualTo( + namesOf( InjectionStrategyGem.values() ) ); + } + + @Test + public void conditionStrategyGemIsCorrect() { + assertThat( namesOf( ConditionStrategy.values() ) ).isEqualTo( + namesOf( ConditionStrategyGem.values() ) ); + } + + @Test + public void classAccesibilityGemIsCorrect() { + assertThat( namesOf( ClassAccessibility.values() ) ).isEqualTo( + namesOf( ClassAccessibilityGem.values() ) ); + } + + private static List namesOf(Enum[] values) { + return Stream.of( values ) + .map( Enum::name ) + .collect( Collectors.toList() ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractIdHoldingTo.java b/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractIdHoldingTo.java index 16d3a59177..3c5e582f20 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractIdHoldingTo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractIdHoldingTo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractTo.java b/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractTo.java index 6fd9d24b23..c0f4c423ef 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractTo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/AbstractTo.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics; - /** * @author Andreas Gudian */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/GenericsTest.java b/processor/src/test/java/org/mapstruct/ap/test/generics/GenericsTest.java index 8bf6213de5..091c59f78d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/GenericsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/GenericsTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian @@ -37,10 +22,9 @@ SourceTargetMapper.class, TargetTo.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class GenericsTest { - @Test + @ProcessorTest @IssueKey("574") public void mapsIdCorrectly() { TargetTo target = new TargetTo(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/Source.java b/processor/src/test/java/org/mapstruct/ap/test/generics/Source.java index 398a4e65e7..9d3b8eb50f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/generics/SourceTargetMapper.java index 9c888551fe..02a29b7993 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/TargetTo.java b/processor/src/test/java/org/mapstruct/ap/test/generics/TargetTo.java index 0ee83d724b..cac761f14b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/TargetTo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/TargetTo.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics; - /** * @author Andreas Gudian * diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperBase.java b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperBase.java index 13e4bfa795..3c0f065b89 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperBase.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics.genericsupertype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperWithGenericSuperClassTest.java b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperWithGenericSuperClassTest.java index 68a720a785..4caa6f5712 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperWithGenericSuperClassTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/MapperWithGenericSuperClassTest.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics.genericsupertype; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Gunnar Morling @@ -37,15 +22,14 @@ MapperBase.class, VesselSearchResultMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class MapperWithGenericSuperClassTest { - @Test + @ProcessorTest public void canCreateImplementationForMapperWithGenericSuperClass() { Vessel vessel = new Vessel(); vessel.setName( "Pacific Queen" ); - SearchResult vessels = new SearchResult(); + SearchResult vessels = new SearchResult<>(); vessels.setValues( Arrays.asList( vessel ) ); vessels.setSize( 1L ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/SearchResult.java b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/SearchResult.java index 90c1722cd3..3c1874a5fc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/SearchResult.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/SearchResult.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics.genericsupertype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/Vessel.java b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/Vessel.java index d23cd631c4..0359c5e73b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/Vessel.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/Vessel.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics.genericsupertype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselDto.java b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselDto.java index cd41e588aa..0a42fb07a3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics.genericsupertype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselSearchResultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselSearchResultMapper.java index 12af7b12de..e291d389c1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselSearchResultMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/genericsupertype/VesselSearchResultMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.generics.genericsupertype; diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/BoundCopyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/BoundCopyMapper.java new file mode 100644 index 0000000000..e3324ac737 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/BoundCopyMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import org.mapstruct.Mapper; + +@Mapper +public interface BoundCopyMapper { + + CollectionSuperTypes copySuperCollection(CollectionSuperTypes collectionSuperTypes); + + CollectionExtendTypes copyExtendsCollection(CollectionExtendTypes collectionExtendTypes); + + MapSuperType copySuperMap(MapSuperType mapSuperType); + + MapExtendType copyExtendMap(MapExtendType mapExtendType); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/BoundDirectCopyTest.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/BoundDirectCopyTest.java new file mode 100644 index 0000000000..d43d319fc3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/BoundDirectCopyTest.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author hduelme + * + */ +public class BoundDirectCopyTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + BoundCopyMapper.class + ); + + @ProcessorTest + @WithClasses({ + SimpleObject.class, + CollectionSuperTypes.class, + CollectionExtendTypes.class, + MapSuperType.class, + MapExtendType.class, + BoundCopyMapper.class + }) + public void shouldCopyBoundedDirectly() { + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionExtendToSuperMapper.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionExtendToSuperMapper.java new file mode 100644 index 0000000000..db511deee4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionExtendToSuperMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CollectionExtendToSuperMapper { + + CollectionExtendToSuperMapper INSTANCE = Mappers.getMapper( CollectionExtendToSuperMapper.class ); + + CollectionSuperTypes toSuper(CollectionExtendTypes extendTypes); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionExtendTypes.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionExtendTypes.java new file mode 100644 index 0000000000..c515950eda --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionExtendTypes.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import java.util.Collection; + +public class CollectionExtendTypes { + + private Collection simpleObjectsCollection; + + public Collection getSimpleObjectsCollection() { + return simpleObjectsCollection; + } + + public void setSimpleObjectsCollection(Collection simpleObjectsCollection) { + this.simpleObjectsCollection = simpleObjectsCollection; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionSuperTypes.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionSuperTypes.java new file mode 100644 index 0000000000..5bb2f1e0da --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/CollectionSuperTypes.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import java.util.Collection; + +public class CollectionSuperTypes { + + private Collection simpleObjectsCollection; + + public Collection getSimpleObjectsCollection() { + return simpleObjectsCollection; + } + + public void setSimpleObjectsCollection(Collection simpleObjectsCollection) { + this.simpleObjectsCollection = simpleObjectsCollection; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/DistinguishBetweenSuperAndExtendTest.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/DistinguishBetweenSuperAndExtendTest.java new file mode 100644 index 0000000000..998943ce1a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/DistinguishBetweenSuperAndExtendTest.java @@ -0,0 +1,81 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import java.util.ArrayList; +import java.util.List; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses(SimpleObject.class) +public class DistinguishBetweenSuperAndExtendTest { + + @ProcessorTest + @WithClasses({ + CollectionExtendTypes.class, + CollectionSuperTypes.class, + ErroneousCollectionSuperToExtendMapper.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCollectionSuperToExtendMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 13, + message = "Can't map property " + + "\"Collection " + + "simpleObjectsCollection\" to " + + "\"Collection " + + "simpleObjectsCollection\". Consider to declare/implement a mapping method: " + + "\"Collection " + + "map(Collection" + + " value)\".") + }) + public void shouldFailOnSuperToExtendMappingForCollection() { + + } + + @ProcessorTest + @WithClasses(ErroneousStreamSuperToExtendMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousStreamSuperToExtendMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 15, + message = "Can't map property " + + "\"Stream " + + "simpleObjectsStream\" to " + + "\"Stream " + + "simpleObjectsStream\". Consider to declare/implement a mapping method: " + + "\"Stream " + + "map(Stream" + + " value)\".") + }) + public void shouldFailOnSuperToExtendMappingForStream() { + + } + + @ProcessorTest + @WithClasses({ + CollectionExtendTypes.class, + CollectionSuperTypes.class, + CollectionExtendToSuperMapper.class + }) + public void shouldMapExtendBoundToSuperBound() { + CollectionExtendTypes collectionExtendTypes = new CollectionExtendTypes(); + List simpleObjects = new ArrayList<>(); + simpleObjects.add( new SimpleObject() ); + collectionExtendTypes.setSimpleObjectsCollection( simpleObjects ); + CollectionSuperTypes result = CollectionExtendToSuperMapper.INSTANCE.toSuper( collectionExtendTypes ); + assertThat( result ).isNotNull(); + assertThat( result.getSimpleObjectsCollection() ).hasSize( 1 ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/ErroneousCollectionSuperToExtendMapper.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/ErroneousCollectionSuperToExtendMapper.java new file mode 100644 index 0000000000..90005c9fd5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/ErroneousCollectionSuperToExtendMapper.java @@ -0,0 +1,14 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import org.mapstruct.Mapper; + +@Mapper +public interface ErroneousCollectionSuperToExtendMapper { + + CollectionExtendTypes map(CollectionSuperTypes types); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/ErroneousStreamSuperToExtendMapper.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/ErroneousStreamSuperToExtendMapper.java new file mode 100644 index 0000000000..8029c029c3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/ErroneousStreamSuperToExtendMapper.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import java.util.stream.Stream; + +import org.mapstruct.Mapper; + +@Mapper +public interface ErroneousStreamSuperToExtendMapper { + + ExtendStreamTypes map(SuperStreamTypes types); + + class ExtendStreamTypes { + private Stream simpleObjectsStream; + + public Stream getSimpleObjectsStream() { + return simpleObjectsStream; + } + + public void setSimpleObjectsStream(Stream simpleObjectsStream) { + this.simpleObjectsStream = simpleObjectsStream; + } + } + + class SuperStreamTypes { + + private Stream simpleObjectsStream; + + public Stream getSimpleObjectsStream() { + return simpleObjectsStream; + } + + public void setSimpleObjectsStream(Stream simpleObjectsStream) { + this.simpleObjectsStream = simpleObjectsStream; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/MapExtendType.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/MapExtendType.java new file mode 100644 index 0000000000..9bb43b43ac --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/MapExtendType.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import java.util.Map; + +public class MapExtendType { + + private Map simpleMap; + + public Map getSimpleMap() { + return simpleMap; + } + + public void setSimpleMap( + Map simpleMap) { + this.simpleMap = simpleMap; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/MapSuperType.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/MapSuperType.java new file mode 100644 index 0000000000..4172efa3de --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/MapSuperType.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +import java.util.Map; + +public class MapSuperType { + + private Map simpleMap; + + public Map getSimpleMap() { + return simpleMap; + } + + public void setSimpleMap( + Map simpleMap) { + this.simpleMap = simpleMap; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/SimpleObject.java b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/SimpleObject.java new file mode 100644 index 0000000000..b4c7da3d80 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/generics/wildcard/SimpleObject.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.generics.wildcard; + +public class SimpleObject { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/Animal.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/Animal.java index a7c43578a6..43cafaf348 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/Animal.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/Animal.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalDto.java index 39ab114b27..74e828f641 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalMapper.java index e4b2809884..3569be375a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/AnimalMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/ErroneousTargetHasNoWriteAccessorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/ErroneousTargetHasNoWriteAccessorMapper.java index eec8c64ded..41097f9ee0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/ErroneousTargetHasNoWriteAccessorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/ErroneousTargetHasNoWriteAccessorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java index c81111b9ba..3bafb776a3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/IgnorePropertyTest.java @@ -1,35 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; -import static org.assertj.core.api.Assertions.assertThat; - import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for ignoring properties during the mapping. @@ -37,10 +22,9 @@ * @author Gunnar Morling */ @WithClasses({ Animal.class, AnimalDto.class, AnimalMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class IgnorePropertyTest { - @Test + @ProcessorTest @IssueKey("72") public void shouldNotPropagateIgnoredPropertyGivenViaTargetAttribute() { Animal animal = new Animal( "Bruno", 100, 23, "black" ); @@ -56,7 +40,7 @@ public void shouldNotPropagateIgnoredPropertyGivenViaTargetAttribute() { assertThat( animalDto.publicColor ).isNull(); } - @Test + @ProcessorTest @IssueKey("1392") public void shouldIgnoreAllTargetPropertiesWithNoUnmappedTargetWarnings() { Animal animal = new Animal( "Bruno", 100, 23, "black" ); @@ -72,7 +56,7 @@ public void shouldIgnoreAllTargetPropertiesWithNoUnmappedTargetWarnings() { assertThat( animalDto.publicColor ).isNull(); } - @Test + @ProcessorTest @IssueKey("337") public void propertyIsIgnoredInReverseMappingWhenSourceIsAlsoSpecifiedICWIgnore() { AnimalDto animalDto = new AnimalDto( "Bruno", 100, 23, "black" ); @@ -86,7 +70,7 @@ public void propertyIsIgnoredInReverseMappingWhenSourceIsAlsoSpecifiedICWIgnore( assertThat( animal.publicColour ).isNull(); } - @Test + @ProcessorTest @IssueKey("833") @WithClasses({Preditor.class, PreditorDto.class, ErroneousTargetHasNoWriteAccessorMapper.class}) @ExpectedCompilationOutcome( @@ -94,9 +78,8 @@ public void propertyIsIgnoredInReverseMappingWhenSourceIsAlsoSpecifiedICWIgnore( diagnostics = { @Diagnostic(type = ErroneousTargetHasNoWriteAccessorMapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "Property \"hasClaws\" has no write accessor in " + - "org.mapstruct.ap.test.ignore.PreditorDto\\.") + line = 22, + message = "Property \"hasClaws\" has no write accessor in PreditorDto.") } ) public void shouldGiveErrorOnMappingForReadOnlyProp() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/Preditor.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/Preditor.java index 6a7deeb3eb..b474d842c0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/Preditor.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/Preditor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/PreditorDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/PreditorDto.java index e20d6f9f12..541c40051f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/PreditorDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/PreditorDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ExpandedToolbox.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ExpandedToolbox.java index ca0b6c53d7..485404fa17 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ExpandedToolbox.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ExpandedToolbox.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.expand; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/FlattenedToolBox.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/FlattenedToolBox.java index a340d57139..90f210bfc3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/FlattenedToolBox.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/FlattenedToolBox.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.expand; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Hammer.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Hammer.java index 760ebe31b7..3514224503 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Hammer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Hammer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.expand; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/IgnorePropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/IgnorePropertyTest.java index 30cd86a787..deaa75bbe7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/IgnorePropertyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/IgnorePropertyTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.expand; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for ignoring properties during the mapping. @@ -38,10 +23,9 @@ FlattenedToolBox.class, ToolBoxMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class IgnorePropertyTest { - @Test + @ProcessorTest @IssueKey("1392") public void shouldIgnoreAll() { FlattenedToolBox toolboxSource = new FlattenedToolBox(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ToolBoxMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ToolBoxMapper.java index b16e89f351..aa8144269c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ToolBoxMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/ToolBoxMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.expand; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Wrench.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Wrench.java index d40d0295e9..8abbdc2a67 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Wrench.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/expand/Wrench.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.expand; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/BaseEntity.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/BaseEntity.java index ddda507356..1314079470 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/BaseEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/BaseEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerDto.java index 6f23727465..fab5c26a82 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerEntity.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerEntity.java index 19f6143699..585c66f002 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/HammerEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/IgnorePropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/IgnorePropertyTest.java index d9ef3b377e..7ff4ea386d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/IgnorePropertyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/IgnorePropertyTest.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; import java.util.Date; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for ignoring properties during the mapping. @@ -43,10 +28,9 @@ WorkBenchEntity.class, ToolMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class IgnorePropertyTest { - @Test + @ProcessorTest @IssueKey("1392") /** * Should not issue warnings on unmapped target properties @@ -67,9 +51,9 @@ public void shouldIgnoreAllExeptOveriddenInherited() { } - @Test - @IssueKey("1392") - public void shouldIgnoreBase() { + @ProcessorTest + @IssueKey("1933") + public void shouldInheritIgnoreByDefaultFromBase() { WorkBenchDto workBenchDto = new WorkBenchDto(); workBenchDto.setArticleName( "MyBench" ); @@ -79,6 +63,26 @@ public void shouldIgnoreBase() { WorkBenchEntity benchTarget = ToolMapper.INSTANCE.mapBench( workBenchDto ); + assertThat( benchTarget ).isNotNull(); + assertThat( benchTarget.getArticleName() ).isNull(); + assertThat( benchTarget.getDescription() ).isEqualTo( "Beautiful" ); + assertThat( benchTarget.getKey() ).isNull(); + assertThat( benchTarget.getModificationDate() ).isNull(); + assertThat( benchTarget.getCreationDate() ).isNull(); + } + + @ProcessorTest + @IssueKey("1933") + public void shouldOnlyIgnoreBase() { + + WorkBenchDto workBenchDto = new WorkBenchDto(); + workBenchDto.setArticleName( "MyBench" ); + workBenchDto.setArticleDescription( "Beautiful" ); + workBenchDto.setCreationDate( new Date() ); + workBenchDto.setModificationDate( new Date() ); + + WorkBenchEntity benchTarget = ToolMapper.INSTANCE.mapBenchWithImplicit( workBenchDto ); + assertThat( benchTarget ).isNotNull(); assertThat( benchTarget.getArticleName() ).isEqualTo( "MyBench" ); assertThat( benchTarget.getDescription() ).isEqualTo( "Beautiful" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolDto.java index 335cbdcc2c..e6eec3a224 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolEntity.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolEntity.java index 94f664ce18..707f00182c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolMapper.java index 7d582b384c..10c3a513f5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/ToolMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; @@ -42,12 +29,21 @@ public interface ToolMapper { @InheritConfiguration( name = "mapBase" ) ToolEntity mapTool(ToolDto source); - // demonstrates that all the businss stuff is mapped (implicit-by-name and defined) + // demonstrates that all the business stuff is mapped only defined because BeanMapping#ignoreByDefault @InheritConfiguration( name = "mapBase" ) @Mapping(target = "description", source = "articleDescription") WorkBenchEntity mapBench(WorkBenchDto source); + // demonstrates that all the business stuff is mapped (implicit-by-name and defined) + @BeanMapping( ignoreByDefault = false ) // needed to override the one from the BeanMapping mapBase + @InheritConfiguration( name = "mapBase" ) + @Mapping(target = "description", source = "articleDescription") + WorkBenchEntity mapBenchWithImplicit(WorkBenchDto source); + // ignore all the base properties by default @BeanMapping( ignoreByDefault = true ) + @Mapping( target = "key", ignore = true) + @Mapping( target = "modificationDate", ignore = true) + @Mapping( target = "creationDate", ignore = true) BaseEntity mapBase(Object o); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchDto.java index ffee3a8e6f..488a6766ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchEntity.java b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchEntity.java index d5dbb37579..0c18779ea5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/ignore/inherit/WorkBenchEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.ignore.inherit; diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/ErroneousSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/ErroneousSourceTargetMapper.java new file mode 100644 index 0000000000..4ec3c64500 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/ErroneousSourceTargetMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignorebydefaultsource; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( + unmappedTargetPolicy = ReportingPolicy.IGNORE, + unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface ErroneousSourceTargetMapper { + ErroneousSourceTargetMapper INSTANCE = Mappers.getMapper( ErroneousSourceTargetMapper.class ); + + @Mapping(source = "one", target = "one") + Target sourceToTarget(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/ErroneousSourceTargetMapperWithIgnoreByDefault.java b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/ErroneousSourceTargetMapperWithIgnoreByDefault.java new file mode 100644 index 0000000000..459e2f426a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/ErroneousSourceTargetMapperWithIgnoreByDefault.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignorebydefaultsource; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +@Mapper( + unmappedTargetPolicy = ReportingPolicy.IGNORE, + unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface ErroneousSourceTargetMapperWithIgnoreByDefault { + ErroneousSourceTargetMapperWithIgnoreByDefault INSTANCE = Mappers.getMapper( + ErroneousSourceTargetMapperWithIgnoreByDefault.class ); + + @Mapping(source = "one", target = "one") + @BeanMapping(ignoreByDefault = true) + Target sourceToTarget(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/IgnoreByDefaultSourcesTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/IgnoreByDefaultSourcesTest.java new file mode 100644 index 0000000000..fce6d49648 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/IgnoreByDefaultSourcesTest.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignorebydefaultsource; + +import javax.tools.Diagnostic.Kind; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +@IssueKey("2560") +public class IgnoreByDefaultSourcesTest { + + @ProcessorTest + @WithClasses({ ErroneousSourceTargetMapperWithIgnoreByDefault.class, Source.class, Target.class }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousSourceTargetMapperWithIgnoreByDefault.class, + kind = Kind.ERROR, + line = 23, + message = "Unmapped source property: \"other\".") + } + ) + public void shouldRaiseErrorDueToNonIgnoredSourcePropertyWithBeanMappingIgnoreByDefault() { + } + + @ProcessorTest + @WithClasses({ ErroneousSourceTargetMapper.class, Source.class, Target.class }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousSourceTargetMapper.class, + kind = Kind.ERROR, + line = 20, + message = "Unmapped source property: \"other\".") + } + ) + public void shouldRaiseErrorDueToNonIgnoredSourceProperty() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/Source.java b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/Source.java new file mode 100644 index 0000000000..81d6441d57 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/Source.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignorebydefaultsource; + +class Source { + private int one; + private int other; + + public int getOne() { + return one; + } + + public void setOne(int one) { + this.one = one; + } + + public int getOther() { + return other; + } + + public void setOther(int other) { + this.other = other; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/Target.java b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/Target.java new file mode 100644 index 0000000000..68ec5c8933 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignorebydefaultsource/Target.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignorebydefaultsource; + +class Target { + private int one; + + public int getOne() { + return one; + } + + public void setOne(int one) { + this.one = one; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/Animal.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/Animal.java new file mode 100644 index 0000000000..223f99f705 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/Animal.java @@ -0,0 +1,64 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +public class Animal { + + //CHECKSTYLE:OFF + public Integer publicAge; + public String publicColour; + //CHECKSTYLE:OFN + private String colour; + private String name; + private int size; + private Integer age; + + // private String colour; + public Animal() { + } + + public Animal(String name, int size, Integer age, String colour) { + this.name = name; + this.size = size; + this.publicAge = age; + this.age = age; + this.publicColour = colour; + this.colour = colour; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public String getColour() { + return colour; + } + + public void setColour( String colour ) { + this.colour = colour; + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/AnimalDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/AnimalDto.java new file mode 100644 index 0000000000..1651f9b56b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/AnimalDto.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +public class AnimalDto { + + //CHECKSTYLE:OFF + public Integer publicAge; + public String publicColor; + //CHECKSTYLE:ON + private String name; + private Integer size; + private Integer age; + private String color; + + public AnimalDto() { + + } + + public AnimalDto(String name, Integer size, Integer age, String color) { + this.name = name; + this.size = size; + this.publicAge = age; + this.age = age; + this.publicColor = color; + this.color = color; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/AnimalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/AnimalMapper.java new file mode 100644 index 0000000000..2753b36070 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/AnimalMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +import org.mapstruct.Ignored; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface AnimalMapper { + + AnimalMapper INSTANCE = Mappers.getMapper( AnimalMapper.class ); + + @Ignored( targets = { "publicAge", "age", "publicColor", "color" } ) + AnimalDto animalToDto( Animal animal ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/ErroneousMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/ErroneousMapper.java new file mode 100644 index 0000000000..b113e715aa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/ErroneousMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +import org.mapstruct.Ignored; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ErroneousMapper { + + ErroneousMapper INSTANCE = Mappers.getMapper( ErroneousMapper.class ); + + @Mapping(target = "name", ignore = true) + @Ignored(targets = { "name", "color", "publicColor" }) + AnimalDto ignoredAndMappingAnimalToDto( Animal animal ); + + @Mapping(target = "publicColor", source = "publicColour") + @Ignored(targets = { "publicColor", "color" }) + AnimalDto ignoredAndMappingAnimalToDtoMap( Animal animal ); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/IgnoredPropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/IgnoredPropertyTest.java new file mode 100644 index 0000000000..bc6fc2f6b7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/IgnoredPropertyTest.java @@ -0,0 +1,102 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test for ignoring properties during the mapping. + * + * @author Ivashin Aleksey + */ +@WithClasses({ Animal.class, AnimalDto.class, Zoo.class, ZooDto.class, ZooMapper.class}) +public class IgnoredPropertyTest { + + @ProcessorTest + @IssueKey("1958") + @WithClasses( { AnimalMapper.class } ) + public void shouldNotPropagateIgnoredPropertyGivenViaTargetAttribute() { + Animal animal = new Animal( "Bruno", 100, 23, "black" ); + + AnimalDto animalDto = AnimalMapper.INSTANCE.animalToDto( animal ); + + assertThat( animalDto ).isNotNull(); + assertThat( animalDto.getName() ).isEqualTo( "Bruno" ); + assertThat( animalDto.getSize() ).isEqualTo( 100 ); + assertThat( animalDto.getAge() ).isNull(); + assertThat( animalDto.publicAge ).isNull(); + assertThat( animalDto.getColor() ).isNull(); + assertThat( animalDto.publicColor ).isNull(); + } + + @ProcessorTest + @IssueKey("1958") + @WithClasses( { ErroneousMapper.class } ) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = "Target property \"name\" must not be mapped more than once." ), + @Diagnostic(type = ErroneousMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 24, + message = "Target property \"publicColor\" must not be mapped more than once." ) + } + ) + public void shouldFailToGenerateMappings() { + } + + @ProcessorTest + @IssueKey("1958") + @WithClasses( { AnimalMapper.class } ) + public void shouldNotPropagateIgnoredInnerPropertyGivenViaTargetAttribute() { + Animal animal = new Animal( "Bruno", 100, 23, "black" ); + Zoo zoo = new Zoo(animal, "Test name", "test address"); + + ZooDto zooDto = ZooMapper.INSTANCE.zooToDto( zoo ); + + assertThat( zooDto ).isNotNull(); + assertThat( zooDto.getName() ).isEqualTo( "Test name" ); + assertThat( zooDto.getAddress() ).isEqualTo( "test address" ); + assertThat( zooDto.getAnimal() ).isNotNull(); + assertThat( zooDto.getAnimal().getName() ).isEqualTo( "Bruno" ); + assertThat( zooDto.getAnimal().getAge() ).isNull(); + assertThat( zooDto.getAnimal().publicAge ).isNull(); + assertThat( zooDto.getAnimal().getColor() ).isNull(); + assertThat( zooDto.getAnimal().publicColor ).isNull(); + assertThat( zooDto.getAnimal().getSize() ).isNull(); + } + + @ProcessorTest + @IssueKey("1958") + @WithClasses( { AnimalMapper.class } ) + public void shouldNotPropagateIgnoredInnerPropertyGivenViaTargetAttribute2() { + Animal animal = new Animal( "Bruno", 100, 23, "black" ); + Zoo zoo = new Zoo(animal, "Test name", "test address"); + + ZooDto zooDto = ZooMapper.INSTANCE.zooToDto2( zoo ); + + assertThat( zooDto ).isNotNull(); + assertThat( zooDto.getName() ).isEqualTo( "Test name" ); + assertThat( zooDto.getAddress() ).isNull(); + assertThat( zooDto.getAnimal() ).isNotNull(); + assertThat( zooDto.getAnimal().getName() ).isEqualTo( "Bruno" ); + assertThat( zooDto.getAnimal().getAge() ).isNull(); + assertThat( zooDto.getAnimal().publicAge ).isNull(); + assertThat( zooDto.getAnimal().getColor() ).isNull(); + assertThat( zooDto.getAnimal().publicColor ).isNull(); + assertThat( zooDto.getAnimal().getSize() ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/Zoo.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/Zoo.java new file mode 100644 index 0000000000..377e03b877 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/Zoo.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +public class Zoo { + + private Animal animal; + + private String name; + + private String address; + + public Zoo() { + } + + public Zoo(Animal animal, String name, String address ) { + this.animal = animal; + this.name = name; + this.address = address; + } + + public Animal getAnimal() { + return animal; + } + + public void setAnimal(Animal animal) { + this.animal = animal; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/ZooDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/ZooDto.java new file mode 100644 index 0000000000..7c062cab4c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/ZooDto.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +public class ZooDto { + + private AnimalDto animal; + + private String name; + + private String address; + + public ZooDto() { + } + + public ZooDto(AnimalDto animal, String name, String address) { + this.animal = animal; + this.name = name; + this.address = address; + } + + public AnimalDto getAnimal() { + return animal; + } + + public void setAnimal(AnimalDto animal) { + this.animal = animal; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignored/ZooMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignored/ZooMapper.java new file mode 100644 index 0000000000..f05e045b5f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignored/ZooMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignored; + +import org.mapstruct.Ignored; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ZooMapper { + + ZooMapper INSTANCE = Mappers.getMapper( ZooMapper.class ); + + @Ignored( prefix = "animal", targets = { "publicAge", "size", "publicColor", "age", "color" } ) + ZooDto zooToDto( Zoo zoo ); + + @Ignored( targets = { "address" } ) + @Ignored( prefix = "animal", targets = { "publicAge", "size", "publicColor", "age", "color" } ) + ZooDto zooToDto2( Zoo zoo ); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/IgnoredMappedPropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/IgnoredMappedPropertyTest.java new file mode 100644 index 0000000000..c50fddd2f7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/IgnoredMappedPropertyTest.java @@ -0,0 +1,136 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped; + +import javax.tools.Diagnostic.Kind; + +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapper; +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapperWithIgnorePolicyInMapperConfig; +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapperWithIgnoreSourcePolicy; +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapperWithWarnPolicyInMapperConfig; +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapperWithWarnSourcePolicy; +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapperWithWarnSourcePolicyInMapper; +import org.mapstruct.ap.test.ignoreunmapped.mapper.UserMapperWithoutBeanMapping; +import org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous.UserMapperWithErrorPolicyInMapperConfig; +import org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous.UserMapperWithErrorSourcePolicy; +import org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous.UserMapperWithErrorSourcePolicyInMapper; +import org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous.UserMapperWithMultiMapping; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +/** + * Verifies that mapped properties listed in ignoreUnmappedSourceProperties trigger a warning. + * + * @author Ritesh Chopade(codeswithritesh) + */ +@IssueKey("3837") +@WithClasses({UserEntity.class, UserDto.class}) +public class IgnoredMappedPropertyTest { + + @ProcessorTest + @WithClasses({ + UserMapper.class, + UserMapperWithIgnoreSourcePolicy.class, + UserMapperWithoutBeanMapping.class, + UserMapperWithIgnorePolicyInMapperConfig.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED + ) + public void shouldNotWarnAboutRedundantIgnore() { + } + + @ProcessorTest + @WithClasses({ + UserMapperWithErrorSourcePolicy.class, + UserMapperWithErrorSourcePolicyInMapper.class, + UserMapperWithErrorPolicyInMapperConfig.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + type = UserMapperWithErrorSourcePolicy.class, + kind = Kind.ERROR, + line = 20, + message = "Source property \"email\" is mapped despite being " + + "listed in ignoreUnmappedSourceProperties." + ), + @Diagnostic( + type = UserMapperWithErrorSourcePolicyInMapper.class, + kind = Kind.ERROR, + line = 19, + message = "Source property \"email\" is mapped despite being " + + "listed in ignoreUnmappedSourceProperties." + ), + @Diagnostic( + type = UserMapperWithErrorPolicyInMapperConfig.class, + kind = Kind.ERROR, + line = 23, + message = "Source property \"email\" is mapped despite being " + + "listed in ignoreUnmappedSourceProperties." + ) + } + ) + public void shouldWarnAboutRedundantIgnoreWithErrorPolicy() { + } + + @ProcessorTest + @WithClasses({ + UserMapperWithWarnSourcePolicy.class, + UserMapperWithWarnSourcePolicyInMapper.class, + UserMapperWithWarnPolicyInMapperConfig.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + type = UserMapperWithWarnSourcePolicy.class, + kind = Kind.WARNING, + line = 20, + message = "Source property \"email\" is mapped despite being " + + "listed in ignoreUnmappedSourceProperties." + ), + @Diagnostic( + type = UserMapperWithWarnSourcePolicyInMapper.class, + kind = Kind.WARNING, + line = 19, + message = "Source property \"email\" is mapped despite being " + + "listed in ignoreUnmappedSourceProperties." + ), + @Diagnostic( + type = UserMapperWithWarnPolicyInMapperConfig.class, + kind = Kind.WARNING, + line = 23, + message = "Source property \"email\" is mapped despite being " + + "listed in ignoreUnmappedSourceProperties." + ) + } + ) + public void shouldWarnAboutRedundantIgnoreWithWarnPolicy() { + } + + @ProcessorTest + @WithClasses({UserMapperWithMultiMapping.class}) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + type = UserMapperWithMultiMapping.class, + kind = Kind.ERROR, + line = 21, + message = "Source properties \"email, username\" are mapped despite " + + "being listed in ignoreUnmappedSourceProperties." + ) + } + ) + public void shouldWarnAboutRedundantIgnoreWithMultiMapping() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/UserDto.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/UserDto.java new file mode 100644 index 0000000000..f153bbe8a7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/UserDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped; + +/** + * @author Ritesh Chopade(codeswithritesh) + */ +public class UserDto { + + private String username; + private String email; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/UserEntity.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/UserEntity.java new file mode 100644 index 0000000000..692cc4aa89 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/UserEntity.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped; + +/** + * @author Ritesh Chopade(codeswithritesh) + */ +public class UserEntity { + + private String username; + private String email; + private String password; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapper.java new file mode 100644 index 0000000000..bcb23677e4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper +public interface UserMapper { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithIgnorePolicyInMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithIgnorePolicyInMapperConfig.java new file mode 100644 index 0000000000..f73e0bc28c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithIgnorePolicyInMapperConfig.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@MapperConfig(unmappedSourcePolicy = ReportingPolicy.IGNORE) +interface IgnorePolicyConfig { } + +@Mapper(config = IgnorePolicyConfig.class) +public interface UserMapperWithIgnorePolicyInMapperConfig { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithIgnoreSourcePolicy.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithIgnoreSourcePolicy.java new file mode 100644 index 0000000000..d844f1229a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithIgnoreSourcePolicy.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper +public interface UserMapperWithIgnoreSourcePolicy { + + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}, unmappedSourcePolicy = ReportingPolicy.IGNORE) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnPolicyInMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnPolicyInMapperConfig.java new file mode 100644 index 0000000000..37184ea0d5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnPolicyInMapperConfig.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@MapperConfig(unmappedSourcePolicy = ReportingPolicy.WARN) +interface WarnPolicyConfig { } + +@Mapper(config = WarnPolicyConfig.class) +public interface UserMapperWithWarnPolicyInMapperConfig { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnSourcePolicy.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnSourcePolicy.java new file mode 100644 index 0000000000..5a67934114 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnSourcePolicy.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper +public interface UserMapperWithWarnSourcePolicy { + + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}, unmappedSourcePolicy = ReportingPolicy.WARN) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnSourcePolicyInMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnSourcePolicyInMapper.java new file mode 100644 index 0000000000..2f34fc336f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithWarnSourcePolicyInMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper(unmappedSourcePolicy = ReportingPolicy.WARN) +public interface UserMapperWithWarnSourcePolicyInMapper { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithoutBeanMapping.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithoutBeanMapping.java new file mode 100644 index 0000000000..10c9065bdf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/UserMapperWithoutBeanMapping.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper +public interface UserMapperWithoutBeanMapping { + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorPolicyInMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorPolicyInMapperConfig.java new file mode 100644 index 0000000000..0d25facd69 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorPolicyInMapperConfig.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MapperConfig; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@MapperConfig(unmappedSourcePolicy = ReportingPolicy.ERROR) +interface ErrorPolicyConfig { } + +@Mapper(config = ErrorPolicyConfig.class) +public interface UserMapperWithErrorPolicyInMapperConfig { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorSourcePolicy.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorSourcePolicy.java new file mode 100644 index 0000000000..db658b3636 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorSourcePolicy.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper +public interface UserMapperWithErrorSourcePolicy { + + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}, unmappedSourcePolicy = ReportingPolicy.ERROR) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorSourcePolicyInMapper.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorSourcePolicyInMapper.java new file mode 100644 index 0000000000..27a867ca61 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithErrorSourcePolicyInMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper(unmappedSourcePolicy = ReportingPolicy.ERROR) +public interface UserMapperWithErrorSourcePolicyInMapper { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email"}) + @Mapping(source = "email", target = "email") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithMultiMapping.java b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithMultiMapping.java new file mode 100644 index 0000000000..388c00de2c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/ignoreunmapped/mapper/erroneous/UserMapperWithMultiMapping.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.ignoreunmapped.mapper.erroneous; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.ignoreunmapped.UserDto; +import org.mapstruct.ap.test.ignoreunmapped.UserEntity; + +@Mapper +public interface UserMapperWithMultiMapping { + @BeanMapping(ignoreUnmappedSourceProperties = {"password", "email", "username"}, + unmappedSourcePolicy = ReportingPolicy.ERROR) + @Mapping(source = "email", target = "email") + @Mapping(source = "username", target = "username") + UserDto map(UserEntity user); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/ConflictingTypesNamesTest.java b/processor/src/test/java/org/mapstruct/ap/test/imports/ConflictingTypesNamesTest.java index f6d42a48ad..8d61eb8f8a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/ConflictingTypesNamesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/ConflictingTypesNamesTest.java @@ -1,28 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.imports.from.Foo; import org.mapstruct.ap.test.imports.from.FooWrapper; import org.mapstruct.ap.test.imports.referenced.GenericMapper; @@ -30,10 +13,13 @@ import org.mapstruct.ap.test.imports.referenced.Source; import org.mapstruct.ap.test.imports.referenced.Target; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxInject; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for generating a mapper which references types whose names clash with names of used annotations and exceptions. * @@ -56,17 +42,13 @@ org.mapstruct.ap.test.imports.to.FooWrapper.class, SecondSourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) +@WithJavaxInject public class ConflictingTypesNamesTest { - private final GeneratedSource generatedSource = new GeneratedSource(); - - @Rule - public GeneratedSource getGeneratedSource() { - return generatedSource; - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest public void mapperImportingTypesWithConflictingNamesCanBeGenerated() { Named source = new Named(); source.setFoo( 123 ); @@ -84,7 +66,7 @@ public void mapperImportingTypesWithConflictingNamesCanBeGenerated() { assertThat( foo2.getName() ).isEqualTo( "bar" ); } - @Test + @ProcessorTest @IssueKey("178") public void mapperHasNoUnnecessaryImports() { Source source = new Source(); @@ -104,7 +86,7 @@ public void mapperHasNoUnnecessaryImports() { generatedSource.forMapper( SecondSourceTargetMapper.class ).containsNoImportFor( NotImportedDatatype.class ); } - @Test + @ProcessorTest @IssueKey("156") public void importsForTargetTypes() { FooWrapper source = new FooWrapper(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/InnerClassesImportsTest.java b/processor/src/test/java/org/mapstruct/ap/test/imports/InnerClassesImportsTest.java index 03a7bbf392..abad5e4177 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/InnerClassesImportsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/InnerClassesImportsTest.java @@ -1,28 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.imports.innerclasses.BeanFacade; import org.mapstruct.ap.test.imports.innerclasses.BeanWithInnerEnum; import org.mapstruct.ap.test.imports.innerclasses.BeanWithInnerEnum.InnerEnum; @@ -31,13 +14,14 @@ import org.mapstruct.ap.test.imports.innerclasses.SourceWithInnerClass; import org.mapstruct.ap.test.imports.innerclasses.SourceWithInnerClass.SourceInnerClass; import org.mapstruct.ap.test.imports.innerclasses.TargetWithInnerClass; -import org.mapstruct.ap.test.imports.innerclasses.TargetWithInnerClass.TargetInnerClass; import org.mapstruct.ap.test.imports.innerclasses.TargetWithInnerClass.TargetInnerClass.TargetInnerInnerClass; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for generating a mapper which references nested types (static inner classes). * @@ -47,17 +31,12 @@ SourceWithInnerClass.class, TargetWithInnerClass.class, InnerClassMapper.class, // BeanFacade.class, BeanWithInnerEnum.class, BeanWithInnerEnumMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class InnerClassesImportsTest { - private final GeneratedSource generatedSource = new GeneratedSource(); - - @Rule - public GeneratedSource getGeneratedSource() { - return generatedSource; - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @IssueKey( "412" ) public void mapperRequiresInnerClassImports() { SourceWithInnerClass source = new SourceWithInnerClass(); @@ -67,11 +46,10 @@ public void mapperRequiresInnerClassImports() { assertThat( target ).isNotNull(); assertThat( target.getInnerClassMember().getValue() ).isEqualTo( 412 ); - generatedSource.forMapper( InnerClassMapper.class ).containsImportFor( SourceInnerClass.class ); - generatedSource.forMapper( InnerClassMapper.class ).containsImportFor( TargetInnerClass.class ); + generatedSource.addComparisonToFixtureFor( InnerClassMapper.class ); } - @Test + @ProcessorTest @IssueKey( "412" ) public void mapperRequiresInnerInnerClassImports() { SourceInnerClass source = new SourceInnerClass(); @@ -81,11 +59,10 @@ public void mapperRequiresInnerInnerClassImports() { assertThat( target ).isNotNull(); assertThat( target.getValue() ).isEqualTo( 412 ); - generatedSource.forMapper( InnerClassMapper.class ).containsImportFor( SourceInnerClass.class ); - generatedSource.forMapper( InnerClassMapper.class ).containsImportFor( TargetInnerInnerClass.class ); + generatedSource.addComparisonToFixtureFor( InnerClassMapper.class ); } - @Test + @ProcessorTest @IssueKey( "209" ) public void mapperRequiresInnerEnumImports() { BeanWithInnerEnum source = new BeanWithInnerEnum(); @@ -102,6 +79,6 @@ public void mapperRequiresInnerEnumImports() { assertThat( sourceAgain ).isNotNull(); assertThat( sourceAgain.getInnerEnum() ).isEqualTo( InnerEnum.A ); - generatedSource.forMapper( BeanWithInnerEnumMapper.class ).containsImportFor( InnerEnum.class ); + generatedSource.addComparisonToFixtureFor( BeanWithInnerEnumMapper.class ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/List.java b/processor/src/test/java/org/mapstruct/ap/test/imports/List.java index d3c1d6a81f..5f49859d8b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/List.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/List.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/Map.java b/processor/src/test/java/org/mapstruct/ap/test/imports/Map.java index db480861e2..f33ce0ac83 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/Map.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/Map.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/Named.java b/processor/src/test/java/org/mapstruct/ap/test/imports/Named.java index c15b7c5710..fd519c7072 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/Named.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/Named.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/ParseException.java b/processor/src/test/java/org/mapstruct/ap/test/imports/ParseException.java index d58aaaddb1..2686ef0833 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/ParseException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/ParseException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/SecondSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/SecondSourceTargetMapper.java index fbbe98eb55..084322002e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/SecondSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/SecondSourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/SourceTargetMapper.java index b894ceee29..845544ba9f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/SourceTargetMapper.java @@ -1,26 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports; import java.util.Date; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.imports.referenced.Source; import org.mapstruct.ap.test.imports.referenced.Target; import org.mapstruct.ap.test.imports.to.Foo; @@ -29,7 +17,7 @@ /** * @author Gunnar Morling */ -@Mapper(componentModel = "jsr330") +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @@ -37,7 +25,7 @@ public interface SourceTargetMapper { ParseException sourceToTarget(Named source); //custom types - Map listToMap(List list); + Value listToMap(List list); java.util.List namedsToExceptions(java.util.List source); @@ -48,4 +36,12 @@ public interface SourceTargetMapper { java.util.Map stringsToDates(java.util.Map stringDates); Target sourceToTarget(Source target); + + class Value { + private T value; + + public Value(List list) { + + } + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/Actor.java b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/Actor.java index 0104cd6b61..c84cbe8ab3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/Actor.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/Actor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorDto.java b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorDto.java index 58159769cb..75d810ce6f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorMapper.java index ef639c9712..2a00059c22 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/ActorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.decorator; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/DecoratorInAnotherPackageTest.java b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/DecoratorInAnotherPackageTest.java index 9ce1f124f3..90249b319e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/DecoratorInAnotherPackageTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/DecoratorInAnotherPackageTest.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.decorator; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.imports.decorator.other.ActorMapperDecorator; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for having a decorator in another package than the mapper interface. @@ -39,10 +24,9 @@ ActorMapper.class, ActorMapperDecorator.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class DecoratorInAnotherPackageTest { - @Test + @ProcessorTest public void shouldApplyDecoratorFromAnotherPackage() { Actor actor = new Actor(); actor.setAwards( 3 ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/other/ActorMapperDecorator.java b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/other/ActorMapperDecorator.java index 1512c21433..dd23661977 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/other/ActorMapperDecorator.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/decorator/other/ActorMapperDecorator.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.decorator.other; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/from/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/imports/from/Foo.java index a8fe60f092..475d98a115 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/from/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/from/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.from; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/from/FooWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/from/FooWrapper.java index 82c34ed1ec..4cf849c65a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/from/FooWrapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/from/FooWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.from; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanFacade.java b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanFacade.java index c88e3114b3..ef584b7f27 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanFacade.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanFacade.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.innerclasses; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnum.java b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnum.java index 39cb43ca49..4be9d9ce5a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnum.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnum.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.innerclasses; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnumMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnumMapper.java index 6390948b74..a3fbf0363b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnumMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/BeanWithInnerEnumMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.innerclasses; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/InnerClassMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/InnerClassMapper.java index 141614e343..8bf5e408e9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/InnerClassMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/InnerClassMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.innerclasses; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/SourceWithInnerClass.java b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/SourceWithInnerClass.java index 108217f71f..fb40268fdc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/SourceWithInnerClass.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/SourceWithInnerClass.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.innerclasses; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/TargetWithInnerClass.java b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/TargetWithInnerClass.java index 86e61fe040..b47bbc80da 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/TargetWithInnerClass.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/innerclasses/TargetWithInnerClass.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.innerclasses; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/NestedImportsTest.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/NestedImportsTest.java new file mode 100644 index 0000000000..37c522e4cd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/NestedImportsTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.imports.nested.other.SourceInOtherPackage; +import org.mapstruct.ap.test.imports.nested.other.TargetInOtherPackage; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + SourceInOtherPackage.class, + TargetInOtherPackage.class, + Source.class, + Target.class +}) +@IssueKey("1386,148") +class NestedImportsTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses( { + SourceInOtherPackageMapper.class + } ) + void shouldGenerateNestedInnerClassesForSourceInOtherPackage() { + generatedSource.addComparisonToFixtureFor( SourceInOtherPackageMapper.class ); + } + + @ProcessorTest + @WithClasses( { + NestedSourceInOtherPackageMapper.class + } ) + void shouldGenerateCorrectImportsForTopLevelClassesFromOnlyNestedInnerClasses() { + generatedSource.addComparisonToFixtureFor( NestedSourceInOtherPackageMapper.class ); + } + + @ProcessorTest + @WithClasses( { + TargetInOtherPackageMapper.class + } ) + void shouldGenerateNestedInnerClassesForTargetInOtherPackage() { + generatedSource.addComparisonToFixtureFor( TargetInOtherPackageMapper.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/NestedSourceInOtherPackageMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/NestedSourceInOtherPackageMapper.java new file mode 100644 index 0000000000..7f98737d1d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/NestedSourceInOtherPackageMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.imports.nested.other.SourceInOtherPackage; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface NestedSourceInOtherPackageMapper { + + Target.Nested map(SourceInOtherPackage.Nested source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/Source.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/Source.java new file mode 100644 index 0000000000..2d2e9aa215 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/Source.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested; + +/** + * @author Filip Hrisafov + */ +public class Source { + + private Nested value; + + public Nested getValue() { + return value; + } + + public void setValue(Nested value) { + this.value = value; + } + + public static class Nested { + + private Inner inner; + + public static class Inner { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public Inner getInner() { + return inner; + } + + public void setInner(Inner inner) { + this.inner = inner; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/SourceInOtherPackageMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/SourceInOtherPackageMapper.java new file mode 100644 index 0000000000..7150823c1a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/SourceInOtherPackageMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.imports.nested.other.SourceInOtherPackage; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SourceInOtherPackageMapper { + + Target map(SourceInOtherPackage source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/Target.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/Target.java new file mode 100644 index 0000000000..78a50fcb15 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/Target.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private Nested value; + + public Nested getValue() { + return value; + } + + public void setValue(Nested value) { + this.value = value; + } + + public static class Nested { + + private Inner inner; + + public static class Inner { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public Inner getInner() { + return inner; + } + + public void setInner(Inner inner) { + this.inner = inner; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/TargetInOtherPackageMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/TargetInOtherPackageMapper.java new file mode 100644 index 0000000000..a40d52eb1c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/TargetInOtherPackageMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.imports.nested.other.TargetInOtherPackage; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface TargetInOtherPackageMapper { + + TargetInOtherPackage map(Source source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/other/SourceInOtherPackage.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/other/SourceInOtherPackage.java new file mode 100644 index 0000000000..f6646c7160 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/other/SourceInOtherPackage.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested.other; + +/** + * @author Filip Hrisafov + */ +public class SourceInOtherPackage { + + private Nested value; + + public Nested getValue() { + return value; + } + + public void setValue(Nested value) { + this.value = value; + } + + public static class Nested { + + private Inner inner; + + public static class Inner { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public Inner getInner() { + return inner; + } + + public void setInner(Inner inner) { + this.inner = inner; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/nested/other/TargetInOtherPackage.java b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/other/TargetInOtherPackage.java new file mode 100644 index 0000000000..da6b596c06 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/nested/other/TargetInOtherPackage.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.imports.nested.other; + +/** + * @author Filip Hrisafov + */ +public class TargetInOtherPackage { + + private Nested value; + + public Nested getValue() { + return value; + } + + public void setValue(Nested value) { + this.value = value; + } + + public static class Nested { + + private Inner inner; + + public static class Inner { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + public Inner getInner() { + return inner; + } + + public void setInner(Inner inner) { + this.inner = inner; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/GenericMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/GenericMapper.java index 30e7cd181c..d4e59a72c2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/GenericMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/GenericMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/NotImportedDatatype.java b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/NotImportedDatatype.java index ca4f3210cf..ae8ff4f1f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/NotImportedDatatype.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/NotImportedDatatype.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Source.java b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Source.java index 4b437d1d81..3c70fe3b2c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Target.java b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Target.java index 8e413dc38e..4503d3b49e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/referenced/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.referenced; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SourceTypeContainsCollectionWithExtendsBoundTest.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SourceTypeContainsCollectionWithExtendsBoundTest.java index d4b0761ce4..37f4b7a0a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SourceTypeContainsCollectionWithExtendsBoundTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SourceTypeContainsCollectionWithExtendsBoundTest.java @@ -1,40 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Collections; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.imports.sourcewithextendsbound.astronautmapper.AstronautMapper; import org.mapstruct.ap.test.imports.sourcewithextendsbound.dto.AstronautDto; import org.mapstruct.ap.test.imports.sourcewithextendsbound.dto.SpaceshipDto; import org.mapstruct.ap.test.imports.sourcewithextendsbound.entity.Astronaut; import org.mapstruct.ap.test.imports.sourcewithextendsbound.entity.Spaceship; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for generating a mapper which references nested types (static inner classes). * @@ -44,17 +29,12 @@ Astronaut.class, Spaceship.class, AstronautDto.class, SpaceshipDto.class, SpaceshipMapper.class, AstronautMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class SourceTypeContainsCollectionWithExtendsBoundTest { - private final GeneratedSource generatedSource = new GeneratedSource(); - - @Rule - public GeneratedSource getGeneratedSource() { - return generatedSource; - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @IssueKey("768") public void generatesImportsForCollectionWithExtendsBoundInSourceType() { Astronaut astronaut = new Astronaut(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SpaceshipMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SpaceshipMapper.java index 1f39d86332..3191b37558 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SpaceshipMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/SpaceshipMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/astronautmapper/AstronautMapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/astronautmapper/AstronautMapper.java index 28328c2065..5316280e43 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/astronautmapper/AstronautMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/astronautmapper/AstronautMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound.astronautmapper; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/AstronautDto.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/AstronautDto.java index 528194da54..0cb2731997 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/AstronautDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/AstronautDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/SpaceshipDto.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/SpaceshipDto.java index 372e491ca7..2b21b2b165 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/SpaceshipDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/dto/SpaceshipDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound.dto; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Astronaut.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Astronaut.java index 3fc48833af..ab73285975 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Astronaut.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Astronaut.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound.entity; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Spaceship.java b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Spaceship.java index f4ec1073f1..d1f95b08ea 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Spaceship.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/sourcewithextendsbound/entity/Spaceship.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.sourcewithextendsbound.entity; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/to/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/imports/to/Foo.java index fd95b22430..2d45dccaab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/to/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/to/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.to; diff --git a/processor/src/test/java/org/mapstruct/ap/test/imports/to/FooWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/imports/to/FooWrapper.java index b685d81977..8fd5b15213 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/imports/to/FooWrapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/imports/to/FooWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.imports.to; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java index 3935f86279..aaf299635e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/InheritanceTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for propagation of attributes inherited from super types. @@ -32,10 +17,9 @@ * @author Gunnar Morling */ @WithClasses({ SourceBase.class, SourceExt.class, TargetBase.class, TargetExt.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class InheritanceTest { - @Test + @ProcessorTest @IssueKey("17") public void shouldMapAttributeFromSuperType() { SourceExt source = createSource(); @@ -45,7 +29,7 @@ public void shouldMapAttributeFromSuperType() { assertResult( target ); } - @Test + @ProcessorTest @IssueKey("19") public void shouldMapAttributeFromSuperTypeUsingTargetParameter() { SourceExt source = createSource(); @@ -56,7 +40,7 @@ public void shouldMapAttributeFromSuperTypeUsingTargetParameter() { assertResult( target ); } - @Test + @ProcessorTest @IssueKey("19") public void shouldMapAttributeFromSuperTypeUsingReturnedTargetParameter() { SourceExt source = createSource(); @@ -69,6 +53,20 @@ public void shouldMapAttributeFromSuperTypeUsingReturnedTargetParameter() { assertResult( target ); } + @ProcessorTest + @IssueKey("1752") + public void shouldMapAttributeFromSuperTypeUsingReturnedTargetParameterAndNullSource() { + + TargetExt target = new TargetExt(); + target.setFoo( 42L ); + target.publicFoo = 52L; + target.setBar( 23 ); + TargetBase result = SourceTargetMapper.INSTANCE.sourceToTargetWithTargetParameterAndReturn( null, target ); + + assertThat( target ).isSameAs( result ); + assertResult( target ); + } + private void assertResult(TargetExt target) { assertThat( target ).isNotNull(); assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) ); @@ -84,7 +82,7 @@ private SourceExt createSource() { return source; } - @Test + @ProcessorTest @IssueKey("17") public void shouldReverseMapAttributeFromSuperType() { TargetExt target = new TargetExt(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java index 5d16ed8ad3..135334b453 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java index 71e661ac5d..61ad6b8083 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceExt.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java index 2a93bc072c..938b2bd4df 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java index fa5966d89c..c0a24f22f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java index f8fb8f824e..4ac8906f28 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/TargetExt.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/AttributeInheritanceTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/AttributeInheritanceTest.java index 9f2c4ab803..7b9f2d6196 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/AttributeInheritanceTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/AttributeInheritanceTest.java @@ -1,44 +1,28 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.attribute; -import static org.assertj.core.api.Assertions.assertThat; - import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for setting an attribute where the target attribute of a super-type. * * @author Gunnar Morling */ -@RunWith(AnnotationProcessorTestRunner.class) public class AttributeInheritanceTest { - @Test + @ProcessorTest @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) public void shouldMapAttributeFromSuperType() { Source source = new Source(); @@ -49,15 +33,16 @@ public void shouldMapAttributeFromSuperType() { assertThat( target.getFoo().toString() ).isEqualTo( "Bob" ); } - @Test + @ProcessorTest @WithClasses({ Source.class, Target.class, ErroneousTargetSourceMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = @Diagnostic( type = ErroneousTargetSourceMapper.class, kind = Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \"java.lang.CharSequence foo\" to \"java.lang.String foo\"" + line = 16, + message = "Can't map property \"CharSequence foo\" to \"String foo\". " + + "Consider to declare/implement a mapping method: \"String map(CharSequence value)\"." )) public void shouldReportErrorDueToUnmappableAttribute() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/ErroneousTargetSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/ErroneousTargetSourceMapper.java index ed5579c20f..89a27d9564 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/ErroneousTargetSourceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/ErroneousTargetSourceMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.attribute; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Source.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Source.java index 9a167027d1..06a024b326 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.attribute; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/SourceTargetMapper.java index 5ffe93bb66..e9c787ab22 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.attribute; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Target.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Target.java index 68499c1d87..bbe6f7fc7a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/attribute/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.attribute; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalFooSource.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalFooSource.java index da772b3b07..2414ba4f75 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalFooSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalFooSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalMappingHelper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalMappingHelper.java index 2db8507f78..d12c19a9b3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalMappingHelper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/AdditionalMappingHelper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ComplexInheritanceTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ComplexInheritanceTest.java index 544dc35ce4..e2dc947d35 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ComplexInheritanceTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ComplexInheritanceTest.java @@ -1,37 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; - import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for propagation of attributes inherited from super types. @@ -43,10 +27,9 @@ SourceExt.class, SourceExt2.class, TargetComposite.class, AdditionalFooSource.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ComplexInheritanceTest { - @Test + @ProcessorTest @IssueKey("34") @WithClasses({ StandaloneSourceCompositeTargetCompositeMapper.class }) public void shouldMapAttributesWithSuperTypeInStandaloneMapper() { @@ -60,7 +43,7 @@ public void shouldMapAttributesWithSuperTypeInStandaloneMapper() { assertThat( target.getProp5() ).containsOnly( 42, 999 ); } - @Test + @ProcessorTest @IssueKey("34") @WithClasses({ SourceCompositeTargetCompositeMapper.class, SourceBaseMappingHelper.class }) public void shouldMapAttributesWithSuperTypeUsingOtherMapper() { @@ -74,19 +57,19 @@ public void shouldMapAttributesWithSuperTypeUsingOtherMapper() { assertThat( target.getProp5() ).containsOnly( 43, 1000 ); } - @Test + @ProcessorTest @IssueKey("34") @WithClasses({ ErroneousSourceCompositeTargetCompositeMapper.class, AdditionalMappingHelper.class }) @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = @Diagnostic( kind = Kind.ERROR, type = ErroneousSourceCompositeTargetCompositeMapper.class, - line = 32, - messageRegExp = - "Ambiguous mapping methods found for mapping property " - + "\"org.mapstruct.ap.test.inheritance.complex.SourceExt prop1\" to .*Reference: " - + ".*Reference .*AdditionalMappingHelper\\.asReference\\(.*SourceBase source\\), " - + ".*Reference .*AdditionalMappingHelper\\.asReference\\(.*AdditionalFooSource source\\)")) + line = 19, + message = "Ambiguous mapping methods found for mapping property \"SourceExt prop1\" to Reference: " + + "Reference AdditionalMappingHelper.asReference(SourceBase source), " + + "Reference AdditionalMappingHelper.asReference(AdditionalFooSource source). " + + "See https://mapstruct.org/faq/#ambiguous for more info.") + ) public void ambiguousMappingMethodsReportError() { } @@ -121,14 +104,14 @@ private SourceBase createSourceBase(int foo) { private SourceExt createSourceExt(int foo) { SourceExt s = new SourceExt(); s.setFoo( foo ); - s.setBar( Long.valueOf( 47 ) ); + s.setBar( 47L ); return s; } private SourceExt2 createSourceExt2(int foo) { SourceExt2 s = new SourceExt2(); s.setFoo( foo ); - s.setBaz( Long.valueOf( 47 ) ); + s.setBaz( 47L ); return s; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ErroneousSourceCompositeTargetCompositeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ErroneousSourceCompositeTargetCompositeMapper.java index 2864c3464d..696b96ef53 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ErroneousSourceCompositeTargetCompositeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/ErroneousSourceCompositeTargetCompositeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/Reference.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/Reference.java index 81a1d3e731..bd6e3aaa74 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/Reference.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/Reference.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBase.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBase.java index cc7124fd02..d9e446e859 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBase.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBaseMappingHelper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBaseMappingHelper.java index baa2270e4e..017b98496b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBaseMappingHelper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceBaseMappingHelper.java @@ -1,26 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; -import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.stream.Collectors; public class SourceBaseMappingHelper { public Reference asReference(SourceBase source) { @@ -46,13 +33,8 @@ public List integerCollectionToNumberList(Collection collection if ( collection == null ) { return null; } - - List list = new ArrayList( collection.size() ); - - for ( Integer original : collection ) { - list.add( Integer.valueOf( original + 1 ) ); - } - - return list; + return collection.stream() + .map( original -> original + 1 ) + .collect( Collectors.toList() ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceComposite.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceComposite.java index 2578d3b909..0bce391871 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceComposite.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceComposite.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceCompositeTargetCompositeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceCompositeTargetCompositeMapper.java index e4156a6464..8cddb58e8b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceCompositeTargetCompositeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceCompositeTargetCompositeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt.java index b5a423d0b2..1cb41b1092 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt2.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt2.java index 094343fb5e..fcc648543d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/SourceExt2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/StandaloneSourceCompositeTargetCompositeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/StandaloneSourceCompositeTargetCompositeMapper.java index 36855a9a75..db8212e8be 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/StandaloneSourceCompositeTargetCompositeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/StandaloneSourceCompositeTargetCompositeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/TargetComposite.java b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/TargetComposite.java index d14946801d..99f92e3a1e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/TargetComposite.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritance/complex/TargetComposite.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritance.complex; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/BoundMappable.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/BoundMappable.java index b378a84bf4..486d3469f8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/BoundMappable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/BoundMappable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/CarMapper.java index 1c3411dbeb..48d1c46f88 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/CarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/FastCarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/FastCarMapper.java index a8917a1014..e16fbbde1c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/FastCarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/FastCarMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/InheritedMappingMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/InheritedMappingMethodTest.java index 7530d1f574..36c7c5ea08 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/InheritedMappingMethodTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/InheritedMappingMethodTest.java @@ -1,50 +1,34 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.inheritedmappingmethod._target.CarDto; import org.mapstruct.ap.test.inheritedmappingmethod._target.FastCarDto; import org.mapstruct.ap.test.inheritedmappingmethod.source.Car; import org.mapstruct.ap.test.inheritedmappingmethod.source.FastCar; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @IssueKey( "274" ) @WithClasses({ Car.class, CarDto.class, UnboundMappable.class, CarMapper.class, // FastCar.class, FastCarDto.class, BoundMappable.class, FastCarMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class InheritedMappingMethodTest { - @Test + @ProcessorTest public void shouldProvideUnboundedMapperInstance() { UnboundMappable instance = CarMapper.INSTANCE; assertThat( instance ).isNotNull(); } - @Test + @ProcessorTest public void shouldMapUsingUnboundedInheretedMappingMethod() { // given CarDto bikeDto = new CarDto(); @@ -58,13 +42,13 @@ public void shouldMapUsingUnboundedInheretedMappingMethod() { assertThat( bike.getHorsepower() ).isEqualTo( 130 ); } - @Test + @ProcessorTest public void shouldProvideBoundedMapperInstance() { BoundMappable instance = FastCarMapper.INSTANCE; assertThat( instance ).isNotNull(); } - @Test + @ProcessorTest public void shouldMapUsingBoundedInheretedMappingMethod() { // given FastCarDto bikeDto = new FastCarDto(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/UnboundMappable.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/UnboundMappable.java index 9719d9ec4a..67d7893320 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/UnboundMappable.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/UnboundMappable.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/CarDto.java index 9df484d42a..31434e7453 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/CarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/FastCarDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/FastCarDto.java index d25a34eb95..347624410e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/FastCarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/_target/FastCarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/Car.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/Car.java index 570d1af031..290f034c4f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/FastCar.java b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/FastCar.java index 2c463962de..a10f6009ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/FastCar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritedmappingmethod/source/FastCar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritedmappingmethod.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java index c9ab6eddc6..56f3a3f649 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedAllConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedConfig.java index 84f29d9abd..f78366ee30 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedDriverConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedDriverConfig.java index 3608617f9b..631252c8f9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedDriverConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedDriverConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java index 5be48cc9e0..55004c9fe2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/AutoInheritedReverseConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleDto.java index a246315036..8433efa910 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleEntity.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleEntity.java index 1dac6cc6f5..cf06c80e9d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/BaseVehicleEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarDto.java index a017026e0e..36323025b0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarEntity.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarEntity.java index 2715a9db57..bcb191e99d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java index 12eed022d4..b52034bf1d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperAllWithAutoInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java index 041f4e172b..cffe1c6caf 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithAutoInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithExplicitInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithExplicitInheritance.java index 0dec597902..fc084c32f3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithExplicitInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperReverseWithExplicitInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithAutoInheritance.java index 25c1ef96c5..3ef9cafa05 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithAutoInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithAutoInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithExplicitInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithExplicitInheritance.java index 0cced4dd12..27fdf14171 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithExplicitInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarMapperWithExplicitInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverEntity.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverEntity.java index defabd2de9..13b14c5904 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverMapperWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverMapperWithAutoInheritance.java index 2302edfcd7..2e08a46dad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverMapperWithAutoInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/CarWithDriverMapperWithAutoInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/DriverDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/DriverDto.java index e8c7c9bad8..9cb059b38e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/DriverDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/DriverDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Config.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Config.java index 4374688099..46afe99dec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Config.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Config.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Mapper.java index 4502e57b17..bbe21398a6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous1Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous2Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous2Mapper.java index 936d710569..06683fd5fd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous2Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous2Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java index ad53c8510e..ac1a7a6a8b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Config.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java index 34fae8634e..b50369af7f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/Erroneous3Mapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java index 8e7dccfb13..7457bda9f9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperAutoInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java index 7a32767a4f..3a5bcfe98e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/ErroneousMapperReverseWithAutoInheritance.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java index 2cd07e7d0b..4d8e0c28ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/InheritFromConfigTest.java @@ -1,40 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; -import static org.assertj.core.api.Assertions.assertThat; - import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ BaseVehicleDto.class, BaseVehicleEntity.class, @@ -48,7 +32,7 @@ @IssueKey("168") public class InheritFromConfigTest { - @Test + @ProcessorTest public void autoInheritedMappingIsApplied() { CarDto carDto = newTestDto(); @@ -57,7 +41,7 @@ public void autoInheritedMappingIsApplied() { assertEntity( carEntity ); } - @Test + @ProcessorTest public void autoInheritedMappingIsAppliedForMappingTarget() { CarDto carDto = newTestDto(); CarEntity carEntity = new CarEntity(); @@ -67,7 +51,7 @@ public void autoInheritedMappingIsAppliedForMappingTarget() { assertEntity( carEntity ); } - @Test + @ProcessorTest public void autoInheritedMappingIsAppliedForMappingTargetWithTwoStepInheritance() { CarDto carDto = newTestDto(); CarEntity carEntity = new CarEntity(); @@ -90,7 +74,7 @@ private CarDto newTestDto() { return carDto; } - @Test + @ProcessorTest public void autoInheritedMappingIsOverriddenAtMethodLevel() { CarDto carDto = newTestDto(); @@ -101,7 +85,7 @@ public void autoInheritedMappingIsOverriddenAtMethodLevel() { assertThat( carEntity.getAuditTrail() ).isEqualTo( "fixed" ); } - @Test + @ProcessorTest public void autoInheritedMappingIsAppliedInReverse() { CarEntity carEntity = new CarEntity(); carEntity.setColor( "red" ); @@ -113,7 +97,7 @@ public void autoInheritedMappingIsAppliedInReverse() { assertThat( carDto.getId() ).isEqualTo( 42L ); } - @Test + @ProcessorTest public void explicitInheritedMappingIsAppliedInReverse() { CarEntity carEntity = new CarEntity(); carEntity.setColor( "red" ); @@ -125,7 +109,7 @@ public void explicitInheritedMappingIsAppliedInReverse() { assertThat( carDto.getId() ).isEqualTo( 42L ); } - @Test + @ProcessorTest @IssueKey( "1065" ) @WithClasses({ CarMapperReverseWithExplicitInheritance.class } ) public void explicitInheritedMappingIsAppliedInReverseDirectlyFromConfig() { @@ -140,7 +124,7 @@ public void explicitInheritedMappingIsAppliedInReverseDirectlyFromConfig() { assertThat( carDto.getId() ).isEqualTo( 42L ); } - @Test + @ProcessorTest @IssueKey( "1255" ) @WithClasses({ CarMapperReverseWithAutoInheritance.class, AutoInheritedReverseConfig.class } ) public void autoInheritedMappingIsAppliedInReverseDirectlyFromConfig() { @@ -155,7 +139,7 @@ public void autoInheritedMappingIsAppliedInReverseDirectlyFromConfig() { assertThat( carDto.getId() ).isEqualTo( 42L ); } - @Test + @ProcessorTest @IssueKey( "1255" ) @WithClasses({ CarMapperAllWithAutoInheritance.class, AutoInheritedAllConfig.class } ) public void autoInheritedMappingIsAppliedInForwardAndReverseDirectlyFromConfig() { @@ -169,7 +153,7 @@ public void autoInheritedMappingIsAppliedInForwardAndReverseDirectlyFromConfig() assertThat( carDto.getId() ).isEqualTo( carDto2.getId() ); } - @Test + @ProcessorTest public void explicitInheritedMappingWithTwoLevelsIsOverriddenAtMethodLevel() { CarDto carDto = newTestDto(); @@ -180,7 +164,7 @@ public void explicitInheritedMappingWithTwoLevelsIsOverriddenAtMethodLevel() { assertThat( carEntity.getAuditTrail() ).isEqualTo( "fixed" ); } - @Test + @ProcessorTest public void explicitInheritedMappingIsApplied() { CarDto carDto = newTestDto(); @@ -189,7 +173,7 @@ public void explicitInheritedMappingIsApplied() { assertEntity( carEntity ); } - @Test + @ProcessorTest @WithClasses({ DriverDto.class, CarWithDriverEntity.class, @@ -208,59 +192,59 @@ public void autoInheritedFromMultipleSources() { assertThat( carWithDriverEntity.getDriverName() ).isEqualTo( "Malcroft" ); } - @Test + @ProcessorTest @WithClasses({ Erroneous1Mapper.class, Erroneous1Config.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Erroneous1Mapper.class, kind = Kind.ERROR, - line = 36, - messageRegExp = "More than one configuration prototype method is applicable. Use @InheritConfiguration" - + " to select one of them explicitly:" - + " .*BaseVehicleEntity baseDtoToEntity\\(.*BaseVehicleDto dto\\)," - + " .*BaseVehicleEntity anythingToEntity\\(java.lang.Object anyting\\)\\."), + line = 23, + message = "More than one configuration prototype method is applicable. Use @InheritConfiguration to " + + "select one of them explicitly: org.mapstruct.ap.test.inheritfromconfig.BaseVehicleEntity " + + "baseDtoToEntity(org.mapstruct.ap.test.inheritfromconfig.BaseVehicleDto dto), org.mapstruct.ap" + + ".test.inheritfromconfig.BaseVehicleEntity anythingToEntity(java.lang.Object anyting)."), @Diagnostic(type = Erroneous1Mapper.class, kind = Kind.WARNING, - line = 36, - messageRegExp = "Unmapped target properties: \"primaryKey, auditTrail\"\\."), + line = 23, + message = "Unmapped target properties: \"primaryKey, auditTrail\"."), @Diagnostic(type = Erroneous1Mapper.class, kind = Kind.ERROR, - line = 42, - messageRegExp = "More than one configuration prototype method is applicable. Use @InheritConfiguration" - + " to select one of them explicitly:" - + " .*BaseVehicleEntity baseDtoToEntity\\(.*BaseVehicleDto dto\\)," - + " .*BaseVehicleEntity anythingToEntity\\(java.lang.Object anyting\\)\\."), + line = 29, + message = "More than one configuration prototype method is applicable. Use @InheritConfiguration to " + + "select one of them explicitly: org.mapstruct.ap.test.inheritfromconfig.BaseVehicleEntity " + + "baseDtoToEntity(org.mapstruct.ap.test.inheritfromconfig.BaseVehicleDto dto), org.mapstruct.ap" + + ".test.inheritfromconfig.BaseVehicleEntity anythingToEntity(java.lang.Object anyting)."), @Diagnostic(type = Erroneous1Mapper.class, kind = Kind.WARNING, - line = 42, - messageRegExp = "Unmapped target property: \"primaryKey\"\\.") + line = 29, + message = "Unmapped target property: \"primaryKey\".") } ) public void erroneous1MultiplePrototypeMethodsMatch() { - } - @Test + @ProcessorTest @WithClasses({ Erroneous2Mapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Erroneous2Mapper.class, kind = Kind.ERROR, - line = 38, - messageRegExp = "Cycle detected while evaluating inherited configurations. Inheritance path:" - + " .*CarEntity toCarEntity1\\(.*CarDto carDto\\)" - + " -> .*CarEntity toCarEntity2\\(.*CarDto carDto\\)" - + " -> void toCarEntity3\\(.*CarDto carDto, @MappingTarget .*CarEntity entity\\)" - + " -> .*CarEntity toCarEntity1\\(.*CarDto carDto\\)") + line = 25, + message = "Cycle detected while evaluating inherited configurations. Inheritance path: org.mapstruct" + + ".ap.test.inheritfromconfig.CarEntity toCarEntity1(org.mapstruct.ap.test.inheritfromconfig.CarDto" + + " carDto) -> org.mapstruct.ap.test.inheritfromconfig.CarEntity toCarEntity2(org.mapstruct.ap.test" + + ".inheritfromconfig.CarDto carDto) -> void toCarEntity3(org.mapstruct.ap.test.inheritfromconfig" + + ".CarDto carDto, @MappingTarget org.mapstruct.ap.test.inheritfromconfig.CarEntity entity) -> org" + + ".mapstruct.ap.test.inheritfromconfig.CarEntity toCarEntity1(org.mapstruct.ap.test" + + ".inheritfromconfig.CarDto carDto)") } ) public void erroneous2InheritanceCycle() { - } - @Test + @ProcessorTest @IssueKey( "1255" ) @WithClasses({ ErroneousMapperAutoInheritance.class, AutoInheritedReverseConfig.class } ) @ExpectedCompilationOutcome( @@ -268,13 +252,13 @@ public void erroneous2InheritanceCycle() { diagnostics = { @Diagnostic(type = ErroneousMapperAutoInheritance.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "Unmapped target properties: \"primaryKey, auditTrail\"\\.") + line = 22, + message = "Unmapped target properties: \"primaryKey, auditTrail\".") } ) public void erroneousWrongReverseConfigInherited() { } - @Test + @ProcessorTest @IssueKey( "1255" ) @WithClasses({ ErroneousMapperReverseWithAutoInheritance.class, AutoInheritedConfig.class } ) @ExpectedCompilationOutcome( @@ -282,29 +266,33 @@ public void erroneousWrongReverseConfigInherited() { } diagnostics = { @Diagnostic(type = ErroneousMapperReverseWithAutoInheritance.class, kind = Kind.ERROR, - line = 36, - messageRegExp = "Unmapped target property: \"id\"\\.") + line = 23, + message = "Unmapped target property: \"id\".") } ) public void erroneousWrongConfigInherited() { } - @Test - @IssueKey( "1255" ) - @WithClasses({ Erroneous3Mapper.class, Erroneous3Config.class } ) + @ProcessorTest + @IssueKey("1255") + @WithClasses({ Erroneous3Mapper.class, Erroneous3Config.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = Erroneous3Mapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "More than one configuration prototype method is applicable. " - + "Use @InheritInverseConfiguration.*"), + line = 22, + message = "More than one configuration prototype method is applicable. Use " + + "@InheritInverseConfiguration to select one of them explicitly: org.mapstruct.ap.test" + + ".inheritfromconfig.BaseVehicleEntity baseDtoToEntity(org.mapstruct.ap.test.inheritfromconfig" + + ".BaseVehicleDto dto), org.mapstruct.ap.test.inheritfromconfig.BaseVehicleEntity baseDtoToEntity2" + + "(org.mapstruct.ap.test.inheritfromconfig.BaseVehicleDto dto)."), @Diagnostic(type = Erroneous3Mapper.class, kind = Kind.ERROR, - line = 35, - messageRegExp = "Unmapped target property: \"id\"\\.") + line = 22, + message = "Unmapped target property: \"id\".") } ) - public void erroneousDuplicateReverse() { } + public void erroneousDuplicateReverse() { + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/NotToBeUsedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/NotToBeUsedMapper.java index eb2f75c297..8ced44989d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/NotToBeUsedMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/NotToBeUsedMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseDto.java index 699ac21370..5937b77654 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseEntity.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseEntity.java index 7a5a2cc3bf..a66a25b16f 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/BaseEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Dto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Dto.java index c8e6f71634..f478452a88 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Dto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Dto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Entity.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Entity.java index 8a5ab0ca52..0d3213977d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Entity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/Car2Entity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarDto.java index a0eb1a8a22..027d7529ac 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarEntity.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarEntity.java index 30e1c42758..ec4e00c18f 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper.java index 511b3c96c2..feee6e27d2 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper.java @@ -1,28 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; +import org.mapstruct.InheritConfiguration; import org.mapstruct.InheritInverseConfiguration; import org.mapstruct.Mapper; import org.mapstruct.Mapping; - -import org.mapstruct.InheritConfiguration; import org.mapstruct.Mappings; import org.mapstruct.factory.Mappers; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper2.java index 97b7db5b6a..f1d6f1437f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper2.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapper2.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapperTest.java index 3aded6b9ec..bc59060e13 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/CarMapperTest.java @@ -1,34 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Date; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -@RunWith(AnnotationProcessorTestRunner.class) +import static org.assertj.core.api.Assertions.assertThat; + @WithClasses({ BaseDto.class, BaseEntity.class, @@ -43,7 +27,7 @@ @IssueKey("1367") public class CarMapperTest { - @Test + @ProcessorTest public void testMapEntityToDto() { CarDto dto = CarMapper.MAPPER.mapTo( newCar() ); assertThat( dto.getDbId() ).isEqualTo( 9L ); @@ -51,7 +35,7 @@ public void testMapEntityToDto() { assertThat( dto.getSeatCount() ).isEqualTo( 5 ); } - @Test + @ProcessorTest public void testMapDtoToEntity() { CarEntity car = CarMapper.MAPPER.mapFrom( newCarDto() ); assertThat( car.getId() ).isEqualTo( 9L ); @@ -61,7 +45,7 @@ public void testMapDtoToEntity() { assertThat( car.getCreationDate() ).isNull(); } - @Test + @ProcessorTest public void testForwardMappingShouldTakePrecedence() { Car2Dto dto = new Car2Dto(); dto.setMaker( "mazda" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/EntityToDtoMappingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/EntityToDtoMappingConfig.java index e764396f4a..60671f8bf6 100755 --- a/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/EntityToDtoMappingConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/inheritfromconfig/multiple/EntityToDtoMappingConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.inheritfromconfig.multiple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/CdiDefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/CdiDefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..bf8b292ec7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/CdiDefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi._default; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithCdi; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jakarta-cdi. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2950") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerCdiDefaultCompileOptionFieldMapper.class, + GenderCdiDefaultCompileOptionFieldMapper.class +}) +@WithCdi +public class CdiDefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveFieldInjection() { + generatedSource.forMapper( CustomerCdiDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import javax.enterprise.context.ApplicationScoped;" ) + .contains( "import javax.inject.Inject;" ) + .contains( "@Inject" + lineSeparator() + " private GenderCdiDefaultCompileOptionFieldMapper" ) + .contains( "@ApplicationScoped" + lineSeparator() + "public class" ) + .doesNotContain( "public CustomerCdiDefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "jakarta.inject" ) + .doesNotContain( "jakarta.enterprise" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/CustomerCdiDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/CustomerCdiDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..ed0ed0a76e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/CustomerCdiDefaultCompileOptionFieldMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, + uses = GenderCdiDefaultCompileOptionFieldMapper.class) +public interface CustomerCdiDefaultCompileOptionFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/GenderCdiDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/GenderCdiDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..14d6a2e0d7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/_default/GenderCdiDefaultCompileOptionFieldMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.CDI) +public interface GenderCdiDefaultCompileOptionFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/CustomerCdiDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/CustomerCdiDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..4c893b7486 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/CustomerCdiDefaultCompileOptionFieldMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi.jakarta; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.CDI, + uses = GenderCdiDefaultCompileOptionFieldMapper.class) +public interface CustomerCdiDefaultCompileOptionFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/GenderCdiDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/GenderCdiDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..8664b0b433 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/GenderCdiDefaultCompileOptionFieldMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi.jakarta; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.CDI) +public interface GenderCdiDefaultCompileOptionFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..55480399a3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,56 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi.jakarta; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithCdi; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaCdi; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jsr330. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2950") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerCdiDefaultCompileOptionFieldMapper.class, + GenderCdiDefaultCompileOptionFieldMapper.class +}) +@WithJakartaCdi +@WithCdi +public class JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveCdiInjection() { + generatedSource.forMapper( CustomerCdiDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import javax.enterprise.context.ApplicationScoped;" ) + .contains( "import javax.inject.Inject;" ) + .contains( "@Inject" + lineSeparator() + " private GenderCdiDefaultCompileOptionFieldMapper" ) + .contains( "@ApplicationScoped" + lineSeparator() + "public class" ) + .doesNotContain( "public CustomerCdiDefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "jakarta.inject" ) + .doesNotContain( "jakarta.enterprise" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/JakartaCdiCdiDefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/JakartaCdiCdiDefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..953747e404 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/cdi/jakarta/JakartaCdiCdiDefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.cdi.jakarta; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaCdi; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jsr330. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2950") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerCdiDefaultCompileOptionFieldMapper.class, + GenderCdiDefaultCompileOptionFieldMapper.class +}) +@WithJakartaCdi +public class JakartaCdiCdiDefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaCdiInjection() { + generatedSource.forMapper( CustomerCdiDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import jakarta.enterprise.context.ApplicationScoped;" ) + .contains( "import jakarta.inject.Inject;" ) + .contains( "@Inject" + lineSeparator() + " private GenderCdiDefaultCompileOptionFieldMapper" ) + .contains( "@ApplicationScoped" + lineSeparator() + "public class" ) + .doesNotContain( "public CustomerCdiDefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ) + .doesNotContain( "javax.enterprise" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/CustomerJakartaDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/CustomerJakartaDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..2fb6ae0d07 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/CustomerJakartaDefaultCompileOptionFieldMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA, + uses = GenderJakartaDefaultCompileOptionFieldMapper.class) +public interface CustomerJakartaDefaultCompileOptionFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/GenderJakartaDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/GenderJakartaDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..da3409ef41 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/GenderJakartaDefaultCompileOptionFieldMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA) +public interface GenderJakartaDefaultCompileOptionFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/JakartaAndJsr330DefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/JakartaAndJsr330DefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..c647605e66 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/JakartaAndJsr330DefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta._default; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jakarta. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaDefaultCompileOptionFieldMapper.class, + GenderJakartaDefaultCompileOptionFieldMapper.class +}) +@WithJakartaInject +@WithJavaxInject +public class JakartaAndJsr330DefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJakartaDefaultCompileOptionFieldMapper" ) + .doesNotContain( "public CustomerJakartaDefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/JakartaDefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/JakartaDefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..8d33ae923f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/_default/JakartaDefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,98 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta._default; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test field injection for component model jakarta. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaDefaultCompileOptionFieldMapper.class, + GenderJakartaDefaultCompileOptionFieldMapper.class +}) +@ComponentScan(basePackageClasses = CustomerJakartaDefaultCompileOptionFieldMapper.class) +@WithJakartaInject +@Configuration +public class JakartaDefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Inject + @Named + private CustomerJakartaDefaultCompileOptionFieldMapper customerMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + + // when + CustomerDto customerDto = customerMapper.asTarget( customerEntity ); + + // then + assertThat( customerDto ).isNotNull(); + assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); + assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); + } + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJakartaDefaultCompileOptionFieldMapper" ) + .doesNotContain( "public CustomerJakartaDefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/CustomerJakartaCompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/CustomerJakartaCompileOptionConstructorMapper.java new file mode 100644 index 0000000000..9775d05c87 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/CustomerJakartaCompileOptionConstructorMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper( componentModel = MappingConstants.ComponentModel.JAKARTA, + uses = GenderJakartaCompileOptionConstructorMapper.class ) +public interface CustomerJakartaCompileOptionConstructorMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/GenderJakartaCompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/GenderJakartaCompileOptionConstructorMapper.java new file mode 100644 index 0000000000..4539bb1c69 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/GenderJakartaCompileOptionConstructorMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA) +public interface GenderJakartaCompileOptionConstructorMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/JakartaAndJsr330CompileOptionConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/JakartaAndJsr330CompileOptionConstructorMapperTest.java new file mode 100644 index 0000000000..c897891b14 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/JakartaAndJsr330CompileOptionConstructorMapperTest.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.compileoptionconstructor; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test constructor injection for component model jakarta with compile option + * mapstruct.defaultInjectionStrategy=constructor + * + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaCompileOptionConstructorMapper.class, + GenderJakartaCompileOptionConstructorMapper.class +}) +@ProcessorOption(name = "mapstruct.defaultInjectionStrategy", value = "constructor") +@WithJakartaInject +@WithJavaxInject +public class JakartaAndJsr330CompileOptionConstructorMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaCompileOptionConstructorMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "private final GenderJakartaCompileOptionConstructorMapper" ) + .contains( "@Inject" + lineSeparator() + + " public CustomerJakartaCompileOptionConstructorMapperImpl" + + "(GenderJakartaCompileOptionConstructorMapper" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/JakartaCompileOptionConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/JakartaCompileOptionConstructorMapperTest.java new file mode 100644 index 0000000000..691d04ea89 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/compileoptionconstructor/JakartaCompileOptionConstructorMapperTest.java @@ -0,0 +1,100 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.compileoptionconstructor; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test constructor injection for component model jakarta with compile option + * mapstruct.defaultInjectionStrategy=constructor + * + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaCompileOptionConstructorMapper.class, + GenderJakartaCompileOptionConstructorMapper.class +}) +@ProcessorOption(name = "mapstruct.defaultInjectionStrategy", value = "constructor") +@ComponentScan(basePackageClasses = CustomerJakartaCompileOptionConstructorMapper.class) +@Configuration +@WithJakartaInject +public class JakartaCompileOptionConstructorMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Autowired + private CustomerJakartaCompileOptionConstructorMapper customerMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + + // when + CustomerDto customerDto = customerMapper.asTarget( customerEntity ); + + // then + assertThat( customerDto ).isNotNull(); + assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); + assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); + } + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaCompileOptionConstructorMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "private final GenderJakartaCompileOptionConstructorMapper" ) + .contains( "@Inject" + lineSeparator() + + " public CustomerJakartaCompileOptionConstructorMapperImpl" + + "(GenderJakartaCompileOptionConstructorMapper" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/ConstructorJakartaConfig.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/ConstructorJakartaConfig.java new file mode 100644 index 0000000000..0bc9bb16e6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/ConstructorJakartaConfig.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.constructor; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; + +/** + * @author Filip Hrisafov + */ +@MapperConfig(componentModel = MappingConstants.ComponentModel.JAKARTA, + injectionStrategy = InjectionStrategy.CONSTRUCTOR) +public interface ConstructorJakartaConfig { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/CustomerJakartaConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/CustomerJakartaConstructorMapper.java new file mode 100644 index 0000000000..73d201cbfb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/CustomerJakartaConstructorMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.constructor; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper( componentModel = MappingConstants.ComponentModel.JAKARTA, + uses = GenderJakartaConstructorMapper.class, + injectionStrategy = InjectionStrategy.CONSTRUCTOR ) +public interface CustomerJakartaConstructorMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/GenderJakartaConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/GenderJakartaConstructorMapper.java new file mode 100644 index 0000000000..7cbd0bb3df --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/GenderJakartaConstructorMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.constructor; + +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(config = ConstructorJakartaConfig.class) +public interface GenderJakartaConstructorMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/JakartaAndJsr330ConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/JakartaAndJsr330ConstructorMapperTest.java new file mode 100644 index 0000000000..03b5dcf2bb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/JakartaAndJsr330ConstructorMapperTest.java @@ -0,0 +1,58 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.constructor; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaConstructorMapper.class, + GenderJakartaConstructorMapper.class, + ConstructorJakartaConfig.class +}) +@ComponentScan(basePackageClasses = CustomerJakartaConstructorMapper.class) +@Configuration +@WithJakartaInject +@WithJavaxInject +public class JakartaAndJsr330ConstructorMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaConstructorMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "private final GenderJakartaConstructorMapper" ) + .contains( "@Inject" + lineSeparator() + + " public CustomerJakartaConstructorMapperImpl(GenderJakartaConstructorMapper" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/JakartaConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/JakartaConstructorMapperTest.java new file mode 100644 index 0000000000..79d33f10d2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/constructor/JakartaConstructorMapperTest.java @@ -0,0 +1,95 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.constructor; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaConstructorMapper.class, + GenderJakartaConstructorMapper.class, + ConstructorJakartaConfig.class +}) +@ComponentScan(basePackageClasses = CustomerJakartaConstructorMapper.class) +@Configuration +@WithJakartaInject +public class JakartaConstructorMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Autowired + private CustomerJakartaConstructorMapper customerMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + + // when + CustomerDto customerDto = customerMapper.asTarget( customerEntity ); + + // then + assertThat( customerDto ).isNotNull(); + assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); + assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); + } + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaConstructorMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "private final GenderJakartaConstructorMapper" ) + .contains( "@Inject" + lineSeparator() + + " public CustomerJakartaConstructorMapperImpl(GenderJakartaConstructorMapper" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/CustomerFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/CustomerFieldMapper.java new file mode 100644 index 0000000000..550d4ee945 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/CustomerFieldMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.field; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA, uses = GenderJakartaFieldMapper.class, + injectionStrategy = InjectionStrategy.FIELD) +public interface CustomerFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/FieldJakartaConfig.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/FieldJakartaConfig.java new file mode 100644 index 0000000000..b3ad9474cf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/FieldJakartaConfig.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.field; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; + +/** + * @author Filip Hrisafov + */ +@MapperConfig(componentModel = MappingConstants.ComponentModel.JAKARTA, injectionStrategy = InjectionStrategy.FIELD) +public interface FieldJakartaConfig { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/GenderJakartaFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/GenderJakartaFieldMapper.java new file mode 100644 index 0000000000..ee5b959307 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/GenderJakartaFieldMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.field; + +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(config = FieldJakartaConfig.class) +public interface GenderJakartaFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/JakartaAndJsr330FieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/JakartaAndJsr330FieldMapperTest.java new file mode 100644 index 0000000000..56ea535571 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/JakartaAndJsr330FieldMapperTest.java @@ -0,0 +1,53 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.field; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerFieldMapper.class, + GenderJakartaFieldMapper.class, + FieldJakartaConfig.class +}) +@IssueKey("2567") +@WithJakartaInject +@WithJavaxInject +public class JakartaAndJsr330FieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerFieldMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJakartaFieldMapper" ) + .doesNotContain( "public CustomerJakartaFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/JakartaFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/JakartaFieldMapperTest.java new file mode 100644 index 0000000000..c588075ca3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/field/JakartaFieldMapperTest.java @@ -0,0 +1,96 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.field; + +import jakarta.inject.Inject; +import jakarta.inject.Named; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerFieldMapper.class, + GenderJakartaFieldMapper.class, + FieldJakartaConfig.class +}) +@IssueKey("2567") +@ComponentScan(basePackageClasses = CustomerFieldMapper.class) +@Configuration +@WithJakartaInject +public class JakartaFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Inject + @Named + private CustomerFieldMapper customerMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + + // when + CustomerDto customerDto = customerMapper.asTarget( customerEntity ); + + // then + assertThat( customerDto ).isNotNull(); + assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); + assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); + } + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerFieldMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJakartaFieldMapper" ) + .doesNotContain( "public CustomerJakartaFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/CustomerJakartaSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/CustomerJakartaSetterMapper.java new file mode 100644 index 0000000000..d422442791 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/CustomerJakartaSetterMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper( componentModel = MappingConstants.ComponentModel.JAKARTA, + uses = GenderJakartaSetterMapper.class, + injectionStrategy = InjectionStrategy.SETTER ) +public interface CustomerJakartaSetterMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/GenderJakartaSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/GenderJakartaSetterMapper.java new file mode 100644 index 0000000000..f0d9b851e9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/GenderJakartaSetterMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.setter; + +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(config = SetterJakartaConfig.class) +public interface GenderJakartaSetterMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/JakartaSetterMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/JakartaSetterMapperTest.java new file mode 100644 index 0000000000..0e051fa759 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/JakartaSetterMapperTest.java @@ -0,0 +1,98 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.setter; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaSetterMapper.class, + GenderJakartaSetterMapper.class, + SetterJakartaConfig.class +}) +@IssueKey("3229") +@ComponentScan(basePackageClasses = CustomerJakartaSetterMapper.class) +@Configuration +@WithJakartaInject +public class JakartaSetterMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Autowired + private CustomerJakartaSetterMapper customerMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + + // when + CustomerDto customerDto = customerMapper.asTarget( customerEntity ); + + // then + assertThat( customerDto ).isNotNull(); + assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); + assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); + } + + @ProcessorTest + public void shouldHaveSetterInjection() { + String method = "@Inject" + lineSeparator() + + " public void setGenderJakartaSetterMapper(GenderJakartaSetterMapper genderJakartaSetterMapper) {" + + lineSeparator() + " this.genderJakartaSetterMapper = genderJakartaSetterMapper;" + + lineSeparator() + " }"; + generatedSource.forMapper( CustomerJakartaSetterMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "private GenderJakartaSetterMapper genderJakartaSetterMapper;" ) + .doesNotContain( "@Inject" + lineSeparator() + " private GenderJakartaSetterMapper" ) + .contains( method ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/SetterJakartaConfig.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/SetterJakartaConfig.java new file mode 100644 index 0000000000..a189244936 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta/setter/SetterJakartaConfig.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; + +/** + * @author Filip Hrisafov + */ +@MapperConfig(componentModel = MappingConstants.ComponentModel.JAKARTA, + injectionStrategy = InjectionStrategy.SETTER) +public interface SetterJakartaConfig { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/CustomerJakartaCdiDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/CustomerJakartaCdiDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..9ec0709f52 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/CustomerJakartaCdiDefaultCompileOptionFieldMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta_cdi._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JAKARTA_CDI, + uses = GenderJakartaCdiDefaultCompileOptionFieldMapper.class) +public interface CustomerJakartaCdiDefaultCompileOptionFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/GenderJakartaCdiDefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/GenderJakartaCdiDefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..0c1aef6ec6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/GenderJakartaCdiDefaultCompileOptionFieldMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta_cdi._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) +public interface GenderJakartaCdiDefaultCompileOptionFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..b542c99c2a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta_cdi._default; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithCdi; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaCdi; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jakarta. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2950") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaCdiDefaultCompileOptionFieldMapper.class, + GenderJakartaCdiDefaultCompileOptionFieldMapper.class +}) +@WithJakartaCdi +@WithCdi +public class JakartaCdiAndCdiDefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJakartaCdiDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import jakarta.enterprise.context.ApplicationScoped;" ) + .contains( "import jakarta.inject.Inject;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJakartaCdiDefaultCompileOptionFieldMapper" ) + .contains( "@ApplicationScoped" + lineSeparator() + "public class" ) + .doesNotContain( "javax.inject" ) + .doesNotContain( "javax.enterprise" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/JakartaCdiDefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/JakartaCdiDefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..57714cdb01 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jakarta_cdi/_default/JakartaCdiDefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jakarta_cdi._default; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaCdi; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jakarta-cdi. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2950") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJakartaCdiDefaultCompileOptionFieldMapper.class, + GenderJakartaCdiDefaultCompileOptionFieldMapper.class +}) +@WithJakartaCdi +public class JakartaCdiDefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveFieldInjection() { + generatedSource.forMapper( CustomerJakartaCdiDefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import jakarta.enterprise.context.ApplicationScoped;" ) + .contains( "import jakarta.inject.Inject;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJakartaCdiDefaultCompileOptionFieldMapper" ) + .contains( "@ApplicationScoped" + lineSeparator() + "public class" ) + .doesNotContain( "public CustomerJakartaCdiDefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ) + .doesNotContain( "javax.enterprise" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/CustomerJsr330DefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/CustomerJsr330DefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..7fcbe97d5a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/CustomerJsr330DefaultCompileOptionFieldMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, + uses = GenderJsr330DefaultCompileOptionFieldMapper.class) +public interface CustomerJsr330DefaultCompileOptionFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/GenderJsr330DefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/GenderJsr330DefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..1ecf720cbf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/GenderJsr330DefaultCompileOptionFieldMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330._default; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) +public interface GenderJsr330DefaultCompileOptionFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/Jsr330DefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/Jsr330DefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..3e562ff39a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/_default/Jsr330DefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330._default; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jsr330. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Andrei Arlou + */ +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJsr330DefaultCompileOptionFieldMapper.class, + GenderJsr330DefaultCompileOptionFieldMapper.class +}) +@WithJavaxInject +public class Jsr330DefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveFieldInjection() { + generatedSource.forMapper( CustomerJsr330DefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import javax.inject.Inject;" ) + .contains( "import javax.inject.Named;" ) + .contains( "import javax.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJsr330DefaultCompileOptionFieldMapper" ) + .doesNotContain( "public CustomerJsr330DefaultCompileOptionFieldMapperImpl(" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/CustomerJsr330CompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/CustomerJsr330CompileOptionConstructorMapper.java new file mode 100644 index 0000000000..02aeaef088 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/CustomerJsr330CompileOptionConstructorMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Andrei Arlou + */ +@Mapper( componentModel = MappingConstants.ComponentModel.JSR330, + uses = GenderJsr330CompileOptionConstructorMapper.class ) +public interface CustomerJsr330CompileOptionConstructorMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/GenderJsr330CompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/GenderJsr330CompileOptionConstructorMapper.java new file mode 100644 index 0000000000..bffcc06bb9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/GenderJsr330CompileOptionConstructorMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) +public interface GenderJsr330CompileOptionConstructorMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/Jsr330CompileOptionConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/Jsr330CompileOptionConstructorMapperTest.java new file mode 100644 index 0000000000..2e4a44861f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/compileoptionconstructor/Jsr330CompileOptionConstructorMapperTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.compileoptionconstructor; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test constructor injection for component model jsr330 with compile option + * mapstruct.defaultInjectionStrategy=constructor + * + * @author Andrei Arlou + */ +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJsr330CompileOptionConstructorMapper.class, + GenderJsr330CompileOptionConstructorMapper.class +}) +@ProcessorOption( name = "mapstruct.defaultInjectionStrategy", value = "constructor") +@WithJavaxInject +public class Jsr330CompileOptionConstructorMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveConstructorInjectionFromCompileOption() { + generatedSource.forMapper( CustomerJsr330CompileOptionConstructorMapper.class ) + .content() + .contains( "import javax.inject.Inject;" ) + .contains( "import javax.inject.Named;" ) + .contains( "import javax.inject.Singleton;" ) + .contains( "private final GenderJsr330CompileOptionConstructorMapper" ) + .contains( "@Inject" + lineSeparator() + + " public CustomerJsr330CompileOptionConstructorMapperImpl" + + "(GenderJsr330CompileOptionConstructorMapper" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/ConstructorJsr330Config.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/ConstructorJsr330Config.java index d83d38f081..177b70d1dc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/ConstructorJsr330Config.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/ConstructorJsr330Config.java @@ -1,29 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.constructor; import org.mapstruct.InjectionStrategy; import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; /** * @author Filip Hrisafov */ -@MapperConfig(componentModel = "jsr330", injectionStrategy = InjectionStrategy.CONSTRUCTOR) +@MapperConfig(componentModel = MappingConstants.ComponentModel.JSR330, + injectionStrategy = InjectionStrategy.CONSTRUCTOR) public interface ConstructorJsr330Config { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/CustomerJsr330ConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/CustomerJsr330ConstructorMapper.java index 2193fe58cb..32ef9d308b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/CustomerJsr330ConstructorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/CustomerJsr330ConstructorMapper.java @@ -1,38 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.constructor; import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; /** * @author Kevin Grüneberg */ -@Mapper( componentModel = "jsr330", +@Mapper( componentModel = MappingConstants.ComponentModel.JSR330, uses = GenderJsr330ConstructorMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR ) public interface CustomerJsr330ConstructorMapper { - @Mapping(source = "gender", target = "gender") + @Mapping(target = "gender", source = "gender") CustomerDto asTarget(CustomerEntity customerEntity); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/GenderJsr330ConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/GenderJsr330ConstructorMapper.java index fa813ce841..8ad1836555 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/GenderJsr330ConstructorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/GenderJsr330ConstructorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.constructor; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/Jsr330ConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/Jsr330ConstructorMapperTest.java index 3f85a13535..b872fc728b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/Jsr330ConstructorMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/constructor/Jsr330ConstructorMapperTest.java @@ -1,44 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.constructor; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; import org.mapstruct.ap.test.injectionstrategy.shared.Gender; import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxInject; import org.mapstruct.ap.testutil.runner.GeneratedSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; import static java.lang.System.lineSeparator; -import static org.assertj.core.api.Assertions.assertThat; /** * Test constructor injection for component model spring. @@ -55,51 +33,19 @@ ConstructorJsr330Config.class }) @IssueKey("571") -@RunWith(AnnotationProcessorTestRunner.class) -@ComponentScan(basePackageClasses = CustomerJsr330ConstructorMapper.class) -@Configuration +@WithJavaxInject public class Jsr330ConstructorMapperTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); - - @Autowired - private CustomerJsr330ConstructorMapper customerMapper; - private ConfigurableApplicationContext context; - - @Before - public void springUp() { - context = new AnnotationConfigApplicationContext( getClass() ); - context.getAutowireCapableBeanFactory().autowireBean( this ); - } - - @After - public void springDown() { - if ( context != null ) { - context.close(); - } - } - - @Test - public void shouldConvertToTarget() { - // given - CustomerEntity customerEntity = new CustomerEntity(); - customerEntity.setName( "Samuel" ); - customerEntity.setGender( Gender.MALE ); - - // when - CustomerDto customerDto = customerMapper.asTarget( customerEntity ); - - // then - assertThat( customerDto ).isNotNull(); - assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); - assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest public void shouldHaveConstructorInjection() { generatedSource.forMapper( CustomerJsr330ConstructorMapper.class ) .content() + .contains( "import javax.inject.Inject;" ) + .contains( "import javax.inject.Named;" ) + .contains( "import javax.inject.Singleton;" ) .contains( "private final GenderJsr330ConstructorMapper" ) .contains( "@Inject" + lineSeparator() + " public CustomerJsr330ConstructorMapperImpl(GenderJsr330ConstructorMapper" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/CustomerJsr330FieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/CustomerJsr330FieldMapper.java index 55dba208dd..a9e02280a6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/CustomerJsr330FieldMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/CustomerJsr330FieldMapper.java @@ -1,32 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.field; import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; /** * @author Kevin Grüneberg */ -@Mapper(componentModel = "jsr330", uses = GenderJsr330FieldMapper.class, injectionStrategy = InjectionStrategy.FIELD) +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, uses = GenderJsr330FieldMapper.class, + injectionStrategy = InjectionStrategy.FIELD) public interface CustomerJsr330FieldMapper { CustomerDto asTarget(CustomerEntity customerEntity); diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/FieldJsr330Config.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/FieldJsr330Config.java index 2dab52dc57..ba3938ae48 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/FieldJsr330Config.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/FieldJsr330Config.java @@ -1,29 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.field; import org.mapstruct.InjectionStrategy; import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; /** * @author Filip Hrisafov */ -@MapperConfig(componentModel = "jsr330", injectionStrategy = InjectionStrategy.FIELD) +@MapperConfig(componentModel = MappingConstants.ComponentModel.JSR330, injectionStrategy = InjectionStrategy.FIELD) public interface FieldJsr330Config { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/GenderJsr330FieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/GenderJsr330FieldMapper.java index b72ec8078c..67ffaf8306 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/GenderJsr330FieldMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/GenderJsr330FieldMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.field; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/Jsr330FieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/Jsr330FieldMapperTest.java index ac42d731af..9f5b31d136 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/Jsr330FieldMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/field/Jsr330FieldMapperTest.java @@ -1,46 +1,22 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.jsr330.field; -import javax.inject.Inject; -import javax.inject.Named; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; import org.mapstruct.ap.test.injectionstrategy.shared.Gender; import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxInject; import org.mapstruct.ap.testutil.runner.GeneratedSource; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; import static java.lang.System.lineSeparator; -import static org.assertj.core.api.Assertions.assertThat; /** * Test field injection for component model spring. @@ -57,52 +33,19 @@ FieldJsr330Config.class }) @IssueKey("571") -@RunWith(AnnotationProcessorTestRunner.class) -@ComponentScan(basePackageClasses = CustomerJsr330FieldMapper.class) -@Configuration +@WithJavaxInject public class Jsr330FieldMapperTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); - - @Inject - @Named - private CustomerJsr330FieldMapper customerMapper; - private ConfigurableApplicationContext context; - - @Before - public void springUp() { - context = new AnnotationConfigApplicationContext( getClass() ); - context.getAutowireCapableBeanFactory().autowireBean( this ); - } - - @After - public void springDown() { - if ( context != null ) { - context.close(); - } - } - - @Test - public void shouldConvertToTarget() { - // given - CustomerEntity customerEntity = new CustomerEntity(); - customerEntity.setName( "Samuel" ); - customerEntity.setGender( Gender.MALE ); - - // when - CustomerDto customerDto = customerMapper.asTarget( customerEntity ); - - // then - assertThat( customerDto ).isNotNull(); - assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); - assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); - } + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest public void shouldHaveFieldInjection() { generatedSource.forMapper( CustomerJsr330FieldMapper.class ) .content() + .contains( "import javax.inject.Inject;" ) + .contains( "import javax.inject.Named;" ) + .contains( "import javax.inject.Singleton;" ) .contains( "@Inject" + lineSeparator() + " private GenderJsr330FieldMapper" ) .doesNotContain( "public CustomerJsr330FieldMapperImpl(" ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/CustomerJsr330DefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/CustomerJsr330DefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..80f5c60ef0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/CustomerJsr330DefaultCompileOptionFieldMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.jakarta; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330, + uses = GenderJsr330DefaultCompileOptionFieldMapper.class) +public interface CustomerJsr330DefaultCompileOptionFieldMapper { + + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/GenderJsr330DefaultCompileOptionFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/GenderJsr330DefaultCompileOptionFieldMapper.java new file mode 100644 index 0000000000..4a9b56c1b2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/GenderJsr330DefaultCompileOptionFieldMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.jakarta; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.JSR330) +public interface GenderJsr330DefaultCompileOptionFieldMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/JakartaAndJsr330DefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/JakartaAndJsr330DefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..da7176fc7a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/JakartaAndJsr330DefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.jakarta; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jsr330. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJsr330DefaultCompileOptionFieldMapper.class, + GenderJsr330DefaultCompileOptionFieldMapper.class +}) +@WithJakartaInject +@WithJavaxInject +public class JakartaAndJsr330DefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJavaxInjection() { + generatedSource.forMapper( CustomerJsr330DefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import javax.inject.Inject;" ) + .contains( "import javax.inject.Named;" ) + .contains( "import javax.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJsr330DefaultCompileOptionFieldMapper" ) + .doesNotContain( "public CustomerJsr330DefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "jakarta.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/JakartaJsr330DefaultCompileOptionFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/JakartaJsr330DefaultCompileOptionFieldMapperTest.java new file mode 100644 index 0000000000..f78721fb1c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/jakarta/JakartaJsr330DefaultCompileOptionFieldMapperTest.java @@ -0,0 +1,53 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.jakarta; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJakartaInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * Test field injection for component model jsr330. + * Default value option mapstruct.defaultInjectionStrategy is "field" + * + * @author Filip Hrisafov + */ +@IssueKey("2567") +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJsr330DefaultCompileOptionFieldMapper.class, + GenderJsr330DefaultCompileOptionFieldMapper.class +}) +@WithJakartaInject +public class JakartaJsr330DefaultCompileOptionFieldMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveJakartaInjection() { + generatedSource.forMapper( CustomerJsr330DefaultCompileOptionFieldMapper.class ) + .content() + .contains( "import jakarta.inject.Inject;" ) + .contains( "import jakarta.inject.Named;" ) + .contains( "import jakarta.inject.Singleton;" ) + .contains( "@Inject" + lineSeparator() + " private GenderJsr330DefaultCompileOptionFieldMapper" ) + .doesNotContain( "public CustomerJsr330DefaultCompileOptionFieldMapperImpl(" ) + .doesNotContain( "javax.inject" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/CustomerJsr330SetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/CustomerJsr330SetterMapper.java new file mode 100644 index 0000000000..ab269f83f8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/CustomerJsr330SetterMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Filip Hrisafov + */ +@Mapper( componentModel = MappingConstants.ComponentModel.JSR330, + uses = GenderJsr330SetterMapper.class, + injectionStrategy = InjectionStrategy.SETTER ) +public interface CustomerJsr330SetterMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/GenderJsr330SetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/GenderJsr330SetterMapper.java new file mode 100644 index 0000000000..d9b2f8ea9c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/GenderJsr330SetterMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.setter; + +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Filip Hrisafov + */ +@Mapper(config = SetterJsr330Config.class) +public interface GenderJsr330SetterMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/Jsr330SetterMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/Jsr330SetterMapperTest.java new file mode 100644 index 0000000000..18ebdfc767 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/Jsr330SetterMapperTest.java @@ -0,0 +1,55 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.setter; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJavaxInject; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static java.lang.System.lineSeparator; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerJsr330SetterMapper.class, + GenderJsr330SetterMapper.class, + SetterJsr330Config.class +}) +@IssueKey("3229") +@WithJavaxInject +public class Jsr330SetterMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveSetterInjection() { + String method = "@Inject" + lineSeparator() + + " public void setGenderJsr330SetterMapper(GenderJsr330SetterMapper genderJsr330SetterMapper) {" + + lineSeparator() + " this.genderJsr330SetterMapper = genderJsr330SetterMapper;" + + lineSeparator() + " }"; + generatedSource.forMapper( CustomerJsr330SetterMapper.class ) + .content() + .contains( "import javax.inject.Inject;" ) + .contains( "import javax.inject.Named;" ) + .contains( "import javax.inject.Singleton;" ) + .contains( "private GenderJsr330SetterMapper genderJsr330SetterMapper;" ) + .doesNotContain( "@Inject" + lineSeparator() + " private GenderJsr330SetterMapper" ) + .contains( method ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/SetterJsr330Config.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/SetterJsr330Config.java new file mode 100644 index 0000000000..2b13a56feb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/jsr330/setter/SetterJsr330Config.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.jsr330.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; + +/** + * @author Filip Hrisafov + */ +@MapperConfig(componentModel = MappingConstants.ComponentModel.JSR330, + injectionStrategy = InjectionStrategy.SETTER) +public interface SetterJsr330Config { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerDto.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerDto.java index 398b890899..6aef16322b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.shared; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerEntity.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerEntity.java index 862e7156a8..6cb99983a5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.shared; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerRecordDto.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerRecordDto.java new file mode 100644 index 0000000000..9160b7c768 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerRecordDto.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.shared; + +import javax.xml.datatype.XMLGregorianCalendar; + +/** + * @author Sjaak Derksen + */ +public class CustomerRecordDto { + + private XMLGregorianCalendar registrationDate; + private CustomerDto customer; + + public XMLGregorianCalendar getRegistrationDate() { + return registrationDate; + } + + public void setRegistrationDate(XMLGregorianCalendar registrationDate) { + this.registrationDate = registrationDate; + } + + public CustomerDto getCustomer() { + return customer; + } + + public void setCustomer(CustomerDto customer) { + this.customer = customer; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerRecordEntity.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerRecordEntity.java new file mode 100644 index 0000000000..0f115fc323 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/CustomerRecordEntity.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.shared; + +import java.util.Date; + +/** + * @author Sjaak Derksen + */ +public class CustomerRecordEntity { + + private Date registrationDate; + private CustomerEntity customer; + + public Date getRegistrationDate() { + return registrationDate; + } + + public void setRegistrationDate(Date registrationDate) { + this.registrationDate = registrationDate; + } + + public CustomerEntity getCustomer() { + return customer; + } + + public void setCustomer(CustomerEntity customer) { + this.customer = customer; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/Gender.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/Gender.java index 5d923ab921..04c104218e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/Gender.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/Gender.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.shared; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/GenderDto.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/GenderDto.java index 567aac964b..66c514c608 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/GenderDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/shared/GenderDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.shared; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/CustomerSpringDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/CustomerSpringDefaultMapper.java index 8c9b38ecb9..c7c2243d59 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/CustomerSpringDefaultMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/CustomerSpringDefaultMapper.java @@ -1,31 +1,19 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring._default; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; /** * @author Filip Hrisafov */ -@Mapper(componentModel = "spring", uses = GenderSpringDefaultMapper.class ) +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = GenderSpringDefaultMapper.class ) public interface CustomerSpringDefaultMapper { CustomerDto asTarget(CustomerEntity customerEntity); diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/GenderSpringDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/GenderSpringDefaultMapper.java index 18085d4072..e49a820994 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/GenderSpringDefaultMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/GenderSpringDefaultMapper.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring._default; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.ValueMapping; import org.mapstruct.ValueMappings; import org.mapstruct.ap.test.injectionstrategy.shared.Gender; @@ -27,7 +15,7 @@ /** * @author Filip Hrisafov */ -@Mapper(componentModel = "spring") +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) public interface GenderSpringDefaultMapper { @ValueMappings({ diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/SpringDefaultMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/SpringDefaultMapperTest.java index e07db6a465..2d9c374721 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/SpringDefaultMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/_default/SpringDefaultMapperTest.java @@ -1,35 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring._default; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; import org.mapstruct.ap.test.injectionstrategy.shared.Gender; import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithSpring; import org.mapstruct.ap.testutil.runner.GeneratedSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; @@ -54,32 +40,32 @@ GenderSpringDefaultMapper.class }) @IssueKey("571") -@RunWith(AnnotationProcessorTestRunner.class) @ComponentScan(basePackageClasses = CustomerSpringDefaultMapper.class) @Configuration +@WithSpring public class SpringDefaultMapperTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); @Autowired private CustomerSpringDefaultMapper customerMapper; private ConfigurableApplicationContext context; - @Before + @BeforeEach public void springUp() { context = new AnnotationConfigApplicationContext( getClass() ); context.getAutowireCapableBeanFactory().autowireBean( this ); } - @After + @AfterEach public void springDown() { if ( context != null ) { context.close(); } } - @Test + @ProcessorTest public void shouldConvertToTarget() { // given CustomerEntity customerEntity = new CustomerEntity(); @@ -95,7 +81,7 @@ public void shouldConvertToTarget() { assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); } - @Test + @ProcessorTest public void shouldHaveFieldInjection() { generatedSource.forMapper( CustomerSpringDefaultMapper.class ) .content() diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomStereotype.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomStereotype.java new file mode 100644 index 0000000000..ebbbfb935e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomStereotype.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.springframework.stereotype.Component; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Component +public @interface CustomStereotype { + String value() default ""; +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringComponentQualifiedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringComponentQualifiedMapper.java new file mode 100644 index 0000000000..984f9a2551 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringComponentQualifiedMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.springframework.stereotype.Component; + +/** + * @author Ben Zegveld + */ +@AnnotateWith( value = Component.class, elements = @AnnotateWith.Element( strings = "AnnotateWithComponent" ) ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING ) +public interface CustomerSpringComponentQualifiedMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringControllerQualifiedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringControllerQualifiedMapper.java new file mode 100644 index 0000000000..7203fad7a9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringControllerQualifiedMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.springframework.stereotype.Controller; + +/** + * @author Jose Carlos Campanero Ortiz + */ +@AnnotateWith( value = Controller.class, elements = @AnnotateWith.Element( strings = "AnnotateWithController" ) ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING ) +public interface CustomerSpringControllerQualifiedMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringCustomStereotypeQualifiedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringCustomStereotypeQualifiedMapper.java new file mode 100644 index 0000000000..18a062497d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringCustomStereotypeQualifiedMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; + +/** + * @author Jose Carlos Campanero Ortiz + */ +@AnnotateWith( + value = CustomStereotype.class, + elements = @AnnotateWith.Element( strings = "AnnotateWithCustomStereotype" ) +) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING ) +public interface CustomerSpringCustomStereotypeQualifiedMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringRepositoryQualifiedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringRepositoryQualifiedMapper.java new file mode 100644 index 0000000000..7bbefbee2b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringRepositoryQualifiedMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.springframework.stereotype.Repository; + +/** + * @author Jose Carlos Campanero Ortiz + */ +@AnnotateWith( value = Repository.class, elements = @AnnotateWith.Element( strings = "AnnotateWithRepository" ) ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING ) +public interface CustomerSpringRepositoryQualifiedMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringServiceQualifiedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringServiceQualifiedMapper.java new file mode 100644 index 0000000000..52dff8ef8f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/CustomerSpringServiceQualifiedMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import org.mapstruct.AnnotateWith; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.springframework.stereotype.Service; + +/** + * @author Jose Carlos Campanero Ortiz + */ +@AnnotateWith( value = Service.class, elements = @AnnotateWith.Element( strings = "AnnotateWithService" ) ) +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING ) +public interface CustomerSpringServiceQualifiedMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/SpringAnnotateWithMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/SpringAnnotateWithMapperTest.java new file mode 100644 index 0000000000..cdc741814c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/annotateWith/SpringAnnotateWithMapperTest.java @@ -0,0 +1,91 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.annotateWith; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * Test field injection for component model spring. + * + * @author Filip Hrisafov + * @author Jose Carlos Campanero Ortiz + */ +@WithClasses({ + CustomerSpringComponentQualifiedMapper.class, + CustomerSpringControllerQualifiedMapper.class, + CustomerSpringServiceQualifiedMapper.class, + CustomerSpringRepositoryQualifiedMapper.class, + CustomStereotype.class, + CustomerSpringCustomStereotypeQualifiedMapper.class +}) +@IssueKey( "1427" ) +@WithSpring +public class SpringAnnotateWithMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void shouldHaveComponentAnnotatedQualifiedMapper() { + + // then + generatedSource.forMapper( CustomerSpringComponentQualifiedMapper.class ) + .content() + .contains( "@Component(value = \"AnnotateWithComponent\")" ) + .doesNotContain( "@Component" + System.lineSeparator() ); + + } + + @ProcessorTest + public void shouldHaveControllerAnnotatedQualifiedMapper() { + + // then + generatedSource.forMapper( CustomerSpringControllerQualifiedMapper.class ) + .content() + .contains( "@Controller(value = \"AnnotateWithController\")" ) + .doesNotContain( "@Component" ); + + } + + @ProcessorTest + public void shouldHaveServiceAnnotatedQualifiedMapper() { + + // then + generatedSource.forMapper( CustomerSpringServiceQualifiedMapper.class ) + .content() + .contains( "@Service(value = \"AnnotateWithService\")" ) + .doesNotContain( "@Component" ); + + } + + @ProcessorTest + public void shouldHaveRepositoryAnnotatedQualifiedMapper() { + + // then + generatedSource.forMapper( CustomerSpringRepositoryQualifiedMapper.class ) + .content() + .contains( "@Repository(value = \"AnnotateWithRepository\")" ) + .doesNotContain( "@Component" ); + + } + + @ProcessorTest + public void shouldHaveCustomStereotypeAnnotatedQualifiedMapper() { + + // then + generatedSource.forMapper( CustomerSpringCustomStereotypeQualifiedMapper.class ) + .content() + .contains( "@CustomStereotype(value = \"AnnotateWithCustomStereotype\")" ) + .doesNotContain( "@Component" ); + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/CustomerRecordSpringCompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/CustomerRecordSpringCompileOptionConstructorMapper.java new file mode 100644 index 0000000000..f411ba506f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/CustomerRecordSpringCompileOptionConstructorMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordEntity; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, + uses = { CustomerSpringCompileOptionConstructorMapper.class, GenderSpringCompileOptionConstructorMapper.class }, + disableSubMappingMethodsGeneration = true) +public interface CustomerRecordSpringCompileOptionConstructorMapper { + + CustomerRecordDto asTarget(CustomerRecordEntity customerRecordEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/CustomerSpringCompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/CustomerSpringCompileOptionConstructorMapper.java new file mode 100644 index 0000000000..3d28e3e49e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/CustomerSpringCompileOptionConstructorMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Andrei Arlou + */ +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, + uses = GenderSpringCompileOptionConstructorMapper.class) +public interface CustomerSpringCompileOptionConstructorMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/GenderSpringCompileOptionConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/GenderSpringCompileOptionConstructorMapper.java new file mode 100644 index 0000000000..096fe91b96 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/GenderSpringCompileOptionConstructorMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.compileoptionconstructor; + +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Andrei Arlou + */ +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING) +public interface GenderSpringCompileOptionConstructorMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/SpringCompileOptionConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/SpringCompileOptionConstructorMapperTest.java new file mode 100644 index 0000000000..c3291a5f3b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/compileoptionconstructor/SpringCompileOptionConstructorMapperTest.java @@ -0,0 +1,116 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.compileoptionconstructor; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junitpioneer.jupiter.DefaultTimeZone; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test constructor injection for component model spring with + * compile option mapstruct.defaultInjectStrategy=constructor + * + * @author Andrei Arlou + */ +@WithClasses( { + CustomerRecordDto.class, + CustomerRecordEntity.class, + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerRecordSpringCompileOptionConstructorMapper.class, + CustomerSpringCompileOptionConstructorMapper.class, + GenderSpringCompileOptionConstructorMapper.class +} ) +@ProcessorOption( name = "mapstruct.defaultInjectionStrategy", value = "constructor") +@ComponentScan(basePackageClasses = CustomerSpringCompileOptionConstructorMapper.class) +@Configuration +@WithSpring +@DefaultTimeZone("Europe/Berlin") +public class SpringCompileOptionConstructorMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Autowired + private CustomerRecordSpringCompileOptionConstructorMapper customerRecordMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() throws Exception { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + CustomerRecordEntity customerRecordEntity = new CustomerRecordEntity(); + customerRecordEntity.setCustomer( customerEntity ); + customerRecordEntity.setRegistrationDate( createDate( "31-08-1982 10:20:56" ) ); + + // when + CustomerRecordDto customerRecordDto = customerRecordMapper.asTarget( customerRecordEntity ); + + // then + assertThat( customerRecordDto ).isNotNull(); + assertThat( customerRecordDto.getCustomer() ).isNotNull(); + assertThat( customerRecordDto.getCustomer().getName() ).isEqualTo( "Samuel" ); + assertThat( customerRecordDto.getCustomer().getGender() ).isEqualTo( GenderDto.M ); + assertThat( customerRecordDto.getRegistrationDate() ).isNotNull(); + assertThat( customerRecordDto.getRegistrationDate().toString() ).isEqualTo( "1982-08-31T10:20:56.000+02:00" ); + } + + private Date createDate(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" ); + return sdf.parse( date ); + } + + @ProcessorTest + public void shouldConstructorInjectionFromCompileOption() { + generatedSource.forMapper( CustomerSpringCompileOptionConstructorMapper.class ) + .content() + .contains( "private final GenderSpringCompileOptionConstructorMapper" ) + .contains( "@Autowired" + lineSeparator() + + " public CustomerSpringCompileOptionConstructorMapperImpl" + + "(GenderSpringCompileOptionConstructorMapper" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/ConstructorSpringConfig.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/ConstructorSpringConfig.java index 33f941afe9..0bb89895cb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/ConstructorSpringConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/ConstructorSpringConfig.java @@ -1,29 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.constructor; import org.mapstruct.InjectionStrategy; import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; /** * @author Filip Hrisafov */ -@MapperConfig(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR) +@MapperConfig(componentModel = MappingConstants.ComponentModel.SPRING, + injectionStrategy = InjectionStrategy.CONSTRUCTOR) public interface ConstructorSpringConfig { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerRecordSpringConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerRecordSpringConstructorMapper.java new file mode 100644 index 0000000000..c2a5862978 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerRecordSpringConstructorMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.constructor; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordEntity; + +/** + * @author Kevin Grüneberg + */ +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, + uses = { CustomerSpringConstructorMapper.class, GenderSpringConstructorMapper.class }, + injectionStrategy = InjectionStrategy.CONSTRUCTOR, + disableSubMappingMethodsGeneration = true) +public interface CustomerRecordSpringConstructorMapper { + + CustomerRecordDto asTarget(CustomerRecordEntity customerRecordEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerSpringConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerSpringConstructorMapper.java index d5812bb8ba..ef7120585d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerSpringConstructorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/CustomerSpringConstructorMapper.java @@ -1,37 +1,25 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.constructor; import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; /** * @author Kevin Grüneberg */ -@Mapper( componentModel = "spring", +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, uses = GenderSpringConstructorMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR ) public interface CustomerSpringConstructorMapper { - @Mapping( source = "gender", target = "gender" ) + @Mapping(target = "gender", source = "gender") CustomerDto asTarget(CustomerEntity customerEntity); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/GenderSpringConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/GenderSpringConstructorMapper.java index bc2667deed..42dfa0f9d5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/GenderSpringConstructorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/GenderSpringConstructorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.constructor; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/SpringConstructorMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/SpringConstructorMapperTest.java index 1b0dba77e8..2594d5c23d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/SpringConstructorMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/constructor/SpringConstructorMapperTest.java @@ -1,35 +1,29 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.constructor; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junitpioneer.jupiter.DefaultTimeZone; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordEntity; import org.mapstruct.ap.test.injectionstrategy.shared.Gender; import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithSpring; import org.mapstruct.ap.testutil.runner.GeneratedSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; @@ -46,57 +40,69 @@ * @author Kevin Grüneberg */ @WithClasses( { + CustomerRecordDto.class, + CustomerRecordEntity.class, CustomerDto.class, CustomerEntity.class, Gender.class, GenderDto.class, + CustomerRecordSpringConstructorMapper.class, CustomerSpringConstructorMapper.class, GenderSpringConstructorMapper.class, ConstructorSpringConfig.class } ) @IssueKey( "571" ) -@RunWith(AnnotationProcessorTestRunner.class) @ComponentScan(basePackageClasses = CustomerSpringConstructorMapper.class) @Configuration +@WithSpring +@DefaultTimeZone("Europe/Berlin") public class SpringConstructorMapperTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + private static TimeZone originalTimeZone; + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); @Autowired - private CustomerSpringConstructorMapper customerMapper; + private CustomerRecordSpringConstructorMapper customerRecordMapper; private ConfigurableApplicationContext context; - @Before + @BeforeEach public void springUp() { context = new AnnotationConfigApplicationContext( getClass() ); context.getAutowireCapableBeanFactory().autowireBean( this ); } - @After + @AfterEach public void springDown() { if ( context != null ) { context.close(); } } - @Test - public void shouldConvertToTarget() { + @ProcessorTest + public void shouldConvertToTarget() throws Exception { // given CustomerEntity customerEntity = new CustomerEntity(); customerEntity.setName( "Samuel" ); customerEntity.setGender( Gender.MALE ); + CustomerRecordEntity customerRecordEntity = new CustomerRecordEntity(); + customerRecordEntity.setCustomer( customerEntity ); + customerRecordEntity.setRegistrationDate( createDate( "31-08-1982 10:20:56" ) ); // when - CustomerDto customerDto = customerMapper.asTarget( customerEntity ); + CustomerRecordDto customerRecordDto = customerRecordMapper.asTarget( customerRecordEntity ); // then - assertThat( customerDto ).isNotNull(); - assertThat( customerDto.getName() ).isEqualTo( "Samuel" ); - assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); + assertThat( customerRecordDto ).isNotNull(); + assertThat( customerRecordDto.getCustomer() ).isNotNull(); + assertThat( customerRecordDto.getCustomer().getName() ).isEqualTo( "Samuel" ); + assertThat( customerRecordDto.getCustomer().getGender() ).isEqualTo( GenderDto.M ); + assertThat( customerRecordDto.getRegistrationDate() ).isNotNull(); + assertThat( customerRecordDto.getRegistrationDate().toString() ).isEqualTo( "1982-08-31T10:20:56.000+02:00" ); } - @Test + @ProcessorTest public void shouldHaveConstructorInjection() { generatedSource.forMapper( CustomerSpringConstructorMapper.class ) .content() @@ -104,4 +110,10 @@ public void shouldHaveConstructorInjection() { .contains( "@Autowired" + lineSeparator() + " public CustomerSpringConstructorMapperImpl(GenderSpringConstructorMapper" ); } + + private Date createDate(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" ); + return sdf.parse( date ); + } + } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/CustomerSpringFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/CustomerSpringFieldMapper.java index d0a685825b..fb8a316c59 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/CustomerSpringFieldMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/CustomerSpringFieldMapper.java @@ -1,32 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.field; import org.mapstruct.InjectionStrategy; import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; /** * @author Kevin Grüneberg */ -@Mapper(componentModel = "spring", uses = GenderSpringFieldMapper.class, injectionStrategy = InjectionStrategy.FIELD) +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, uses = GenderSpringFieldMapper.class, + injectionStrategy = InjectionStrategy.FIELD) public interface CustomerSpringFieldMapper { CustomerDto asTarget(CustomerEntity customerEntity); diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/FieldSpringConfig.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/FieldSpringConfig.java index f712d14788..c9e3c3f0f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/FieldSpringConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/FieldSpringConfig.java @@ -1,29 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.field; import org.mapstruct.InjectionStrategy; import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; /** * @author Filip Hrisafov */ -@MapperConfig(componentModel = "spring", injectionStrategy = InjectionStrategy.FIELD) +@MapperConfig(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.FIELD) public interface FieldSpringConfig { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/GenderSpringFieldMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/GenderSpringFieldMapper.java index 655a640a8a..49bf3ee017 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/GenderSpringFieldMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/GenderSpringFieldMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.field; diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/SpringFieldMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/SpringFieldMapperTest.java index 37ac7ff989..d464dd5b16 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/SpringFieldMapperTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/field/SpringFieldMapperTest.java @@ -1,35 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.injectionstrategy.spring.field; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; import org.mapstruct.ap.test.injectionstrategy.shared.Gender; import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithSpring; import org.mapstruct.ap.testutil.runner.GeneratedSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ConfigurableApplicationContext; @@ -55,32 +41,32 @@ FieldSpringConfig.class }) @IssueKey("571") -@RunWith(AnnotationProcessorTestRunner.class) @ComponentScan(basePackageClasses = CustomerSpringFieldMapper.class) @Configuration +@WithSpring public class SpringFieldMapperTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); @Autowired private CustomerSpringFieldMapper customerMapper; private ConfigurableApplicationContext context; - @Before + @BeforeEach public void springUp() { context = new AnnotationConfigApplicationContext( getClass() ); context.getAutowireCapableBeanFactory().autowireBean( this ); } - @After + @AfterEach public void springDown() { if ( context != null ) { context.close(); } } - @Test + @ProcessorTest public void shouldConvertToTarget() { // given CustomerEntity customerEntity = new CustomerEntity(); @@ -96,7 +82,7 @@ public void shouldConvertToTarget() { assertThat( customerDto.getGender() ).isEqualTo( GenderDto.M ); } - @Test + @ProcessorTest public void shouldHaveFieldInjection() { generatedSource.forMapper( CustomerSpringFieldMapper.class ) .content() diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/CustomerRecordSpringSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/CustomerRecordSpringSetterMapper.java new file mode 100644 index 0000000000..1d09bdda03 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/CustomerRecordSpringSetterMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordEntity; + +/** + * @author Lucas Resch + */ +@Mapper(componentModel = MappingConstants.ComponentModel.SPRING, + uses = { CustomerSpringSetterMapper.class, GenderSpringSetterMapper.class }, + injectionStrategy = InjectionStrategy.SETTER) +public interface CustomerRecordSpringSetterMapper { + + CustomerRecordDto asTarget(CustomerRecordEntity customerRecordEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/CustomerSpringSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/CustomerSpringSetterMapper.java new file mode 100644 index 0000000000..67dbab5e9c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/CustomerSpringSetterMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingConstants; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; + +/** + * @author Lucas Resch + */ +@Mapper( componentModel = MappingConstants.ComponentModel.SPRING, + uses = GenderSpringSetterMapper.class, + injectionStrategy = InjectionStrategy.SETTER ) +public interface CustomerSpringSetterMapper { + + @Mapping(target = "gender", source = "gender") + CustomerDto asTarget(CustomerEntity customerEntity); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/GenderSpringSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/GenderSpringSetterMapper.java new file mode 100644 index 0000000000..6243465ab5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/GenderSpringSetterMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.setter; + +import org.mapstruct.Mapper; +import org.mapstruct.ValueMapping; +import org.mapstruct.ValueMappings; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; + +/** + * @author Lucas Resch + */ +@Mapper(config = SetterSpringConfig.class) +public interface GenderSpringSetterMapper { + + @ValueMappings({ + @ValueMapping(source = "MALE", target = "M"), + @ValueMapping(source = "FEMALE", target = "F") + }) + GenderDto mapToDto(Gender gender); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/SetterSpringConfig.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/SetterSpringConfig.java new file mode 100644 index 0000000000..18227f315a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/SetterSpringConfig.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.setter; + +import org.mapstruct.InjectionStrategy; +import org.mapstruct.MapperConfig; +import org.mapstruct.MappingConstants; + +/** + * @author Lucas Resch + */ +@MapperConfig(componentModel = MappingConstants.ComponentModel.SPRING, injectionStrategy = InjectionStrategy.SETTER) +public interface SetterSpringConfig { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/SpringSetterMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/SpringSetterMapperTest.java new file mode 100644 index 0000000000..4dcf098a9e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/injectionstrategy/spring/setter/SpringSetterMapperTest.java @@ -0,0 +1,119 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.injectionstrategy.spring.setter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junitpioneer.jupiter.DefaultTimeZone; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordDto; +import org.mapstruct.ap.test.injectionstrategy.shared.CustomerRecordEntity; +import org.mapstruct.ap.test.injectionstrategy.shared.Gender; +import org.mapstruct.ap.test.injectionstrategy.shared.GenderDto; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithSpring; +import org.mapstruct.ap.testutil.runner.GeneratedSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +import static java.lang.System.lineSeparator; +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Test setter injection for component model spring. + * + * @author Lucas Resch + */ +@WithClasses( { + CustomerRecordDto.class, + CustomerRecordEntity.class, + CustomerDto.class, + CustomerEntity.class, + Gender.class, + GenderDto.class, + CustomerRecordSpringSetterMapper.class, + CustomerSpringSetterMapper.class, + GenderSpringSetterMapper.class, + SetterSpringConfig.class +} ) +@IssueKey( "3229" ) +@ComponentScan(basePackageClasses = CustomerSpringSetterMapper.class) +@Configuration +@WithSpring +@DefaultTimeZone("Europe/Berlin") +public class SpringSetterMapperTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @Autowired + private CustomerRecordSpringSetterMapper customerRecordMapper; + private ConfigurableApplicationContext context; + + @BeforeEach + public void springUp() { + context = new AnnotationConfigApplicationContext( getClass() ); + context.getAutowireCapableBeanFactory().autowireBean( this ); + } + + @AfterEach + public void springDown() { + if ( context != null ) { + context.close(); + } + } + + @ProcessorTest + public void shouldConvertToTarget() throws Exception { + // given + CustomerEntity customerEntity = new CustomerEntity(); + customerEntity.setName( "Samuel" ); + customerEntity.setGender( Gender.MALE ); + CustomerRecordEntity customerRecordEntity = new CustomerRecordEntity(); + customerRecordEntity.setCustomer( customerEntity ); + customerRecordEntity.setRegistrationDate( createDate( "31-08-1982 10:20:56" ) ); + + // when + CustomerRecordDto customerRecordDto = customerRecordMapper.asTarget( customerRecordEntity ); + + // then + assertThat( customerRecordDto ).isNotNull(); + assertThat( customerRecordDto.getCustomer() ).isNotNull(); + assertThat( customerRecordDto.getCustomer().getName() ).isEqualTo( "Samuel" ); + assertThat( customerRecordDto.getCustomer().getGender() ).isEqualTo( GenderDto.M ); + assertThat( customerRecordDto.getRegistrationDate() ).isNotNull(); + assertThat( customerRecordDto.getRegistrationDate() ).hasToString( "1982-08-31T10:20:56.000+02:00" ); + } + + @ProcessorTest + public void shouldHaveSetterInjection() { + String method = "@Autowired" + lineSeparator() + + " public void setGenderSpringSetterMapper(GenderSpringSetterMapper genderSpringSetterMapper) {" + + lineSeparator() + " this.genderSpringSetterMapper = genderSpringSetterMapper;" + + lineSeparator() + " }"; + generatedSource.forMapper( CustomerSpringSetterMapper.class ) + .content() + .contains( "private GenderSpringSetterMapper genderSpringSetterMapper;" ) + .contains( method ); + } + + private Date createDate(String date) throws ParseException { + SimpleDateFormat sdf = new SimpleDateFormat( "dd-M-yyyy hh:mm:ss" ); + return sdf.parse( date ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/Colour.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/Colour.java index 023baa52e1..e1f89276e0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/Colour.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/Colour.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/Source.java index 98f37575c0..feea09626c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; @@ -29,6 +16,10 @@ public class Source { private Stream integerStream; + private Stream integerStream2; + + private Stream integerArrayStream; + private Stream anotherIntegerStream; private Stream colours; @@ -37,6 +28,8 @@ public class Source { private Stream stringStream3; + private Stream> streamWithGenerics; + public Stream getStringStream() { return stringStream; } @@ -69,6 +62,22 @@ public void setIntegerStream(Stream integerStream) { this.integerStream = integerStream; } + public Stream getIntegerStream2() { + return integerStream2; + } + + public void setIntegerStream2(Stream integerStream2) { + this.integerStream2 = integerStream2; + } + + public Stream getIntegerArrayStream() { + return integerArrayStream; + } + + public void setIntegerArrayStream(Stream integerArrayStream) { + this.integerArrayStream = integerArrayStream; + } + public Stream getAnotherIntegerStream() { return anotherIntegerStream; } @@ -100,4 +109,12 @@ public Stream getStringStream3() { public void setStringStream3(Stream stringStream3) { this.stringStream3 = stringStream3; } + + public Stream> getStreamWithGenerics() { + return streamWithGenerics; + } + + public void setStreamWithGenerics(Stream> streamWithGenerics) { + this.streamWithGenerics = streamWithGenerics; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/SourceTargetMapper.java index c2e3c5b39e..089e3de156 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; @@ -35,13 +22,16 @@ public abstract class SourceTargetMapper { static final SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); @Mappings({ - @Mapping(source = "stringStream", target = "stringList"), - @Mapping(source = "stringArrayStream", target = "stringArrayList"), - @Mapping(source = "stringStreamToSet", target = "stringSet"), - @Mapping(source = "integerStream", target = "integerCollection"), - @Mapping(source = "anotherIntegerStream", target = "anotherStringSet"), - @Mapping(source = "stringStream2", target = "stringListNoSetter"), - @Mapping(source = "stringStream3", target = "nonGenericStringList") + @Mapping(target = "stringList", source = "stringStream"), + @Mapping(target = "stringArrayList", source = "stringArrayStream"), + @Mapping(target = "stringSet", source = "stringStreamToSet"), + @Mapping(target = "integerCollection", source = "integerStream"), + @Mapping(target = "integerArray", source = "integerStream2"), + @Mapping(target = "integerMultiArray", source = "integerArrayStream"), + @Mapping(target = "anotherStringSet", source = "anotherIntegerStream"), + @Mapping(target = "stringListNoSetter", source = "stringStream2"), + @Mapping(target = "nonGenericStringList", source = "stringStream3"), + @Mapping(target = "arrayWithGenerics", source = "streamWithGenerics") }) public abstract Target sourceToTarget(Source source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/StreamMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/StreamMappingTest.java index da4b162019..d62b1fc384 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/StreamMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/StreamMappingTest.java @@ -1,36 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; import java.util.Arrays; -import java.util.EnumSet; import java.util.HashSet; import java.util.Set; +import java.util.stream.Stream; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Source.class, @@ -42,10 +27,9 @@ StringHolder.class }) @IssueKey( "962" ) -@RunWith(AnnotationProcessorTestRunner.class) public class StreamMappingTest { - @Test + @ProcessorTest public void shouldMapNullList() { Source source = new Source(); @@ -55,7 +39,7 @@ public void shouldMapNullList() { assertThat( target.getStringList() ).isNull(); } - @Test + @ProcessorTest public void shouldReverseMapNullList() { Target target = new Target(); @@ -65,10 +49,10 @@ public void shouldReverseMapNullList() { assertThat( source.getStringStream() ).isNull(); } - @Test + @ProcessorTest public void shouldMapList() { Source source = new Source(); - source.setStringStream( Arrays.asList( "Bob", "Alice" ).stream() ); + source.setStringStream( Stream.of( "Bob", "Alice" ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -76,10 +60,10 @@ public void shouldMapList() { assertThat( target.getStringList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldMapListWithoutSetter() { Source source = new Source(); - source.setStringStream2( Arrays.asList( "Bob", "Alice" ).stream() ); + source.setStringStream2( Stream.of( "Bob", "Alice" ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -87,7 +71,7 @@ public void shouldMapListWithoutSetter() { assertThat( target.getStringListNoSetter() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldReverseMapList() { Target target = new Target(); target.setStringList( Arrays.asList( "Bob", "Alice" ) ); @@ -98,10 +82,10 @@ public void shouldReverseMapList() { assertThat( source.getStringStream() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldMapArrayList() { Source source = new Source(); - source.setStringArrayStream( new ArrayList( Arrays.asList( "Bob", "Alice" ) ).stream() ); + source.setStringArrayStream( new ArrayList<>( Arrays.asList( "Bob", "Alice" ) ).stream() ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -109,10 +93,10 @@ public void shouldMapArrayList() { assertThat( target.getStringArrayList() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldReverseMapArrayList() { Target target = new Target(); - target.setStringArrayList( new ArrayList( Arrays.asList( "Bob", "Alice" ) ) ); + target.setStringArrayList( new ArrayList<>( Arrays.asList( "Bob", "Alice" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -120,10 +104,10 @@ public void shouldReverseMapArrayList() { assertThat( source.getStringArrayStream() ).containsExactly( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldMapSet() { Source source = new Source(); - source.setStringStreamToSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ).stream() ); + source.setStringStreamToSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ).stream() ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -131,10 +115,10 @@ public void shouldMapSet() { assertThat( target.getStringSet() ).contains( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldReverseMapSet() { Target target = new Target(); - target.setStringSet( new HashSet( Arrays.asList( "Bob", "Alice" ) ) ); + target.setStringSet( new HashSet<>( Arrays.asList( "Bob", "Alice" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -142,10 +126,10 @@ public void shouldReverseMapSet() { assertThat( source.getStringStreamToSet() ).contains( "Bob", "Alice" ); } - @Test + @ProcessorTest public void shouldMapListToCollection() { Source source = new Source(); - source.setIntegerStream( Arrays.asList( 1, 2 ).stream() ); + source.setIntegerStream( Stream.of( 1, 2 ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -153,7 +137,7 @@ public void shouldMapListToCollection() { assertThat( target.getIntegerCollection() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest public void shouldReverseMapListToCollection() { Target target = new Target(); target.setIntegerCollection( Arrays.asList( 1, 2 ) ); @@ -164,10 +148,10 @@ public void shouldReverseMapListToCollection() { assertThat( source.getIntegerStream() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest public void shouldMapIntegerSetToStringSet() { Source source = new Source(); - source.setAnotherIntegerStream( new HashSet( Arrays.asList( 1, 2 ) ).stream() ); + source.setAnotherIntegerStream( new HashSet<>( Arrays.asList( 1, 2 ) ).stream() ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -175,10 +159,10 @@ public void shouldMapIntegerSetToStringSet() { assertThat( target.getAnotherStringSet() ).containsOnly( "1", "2" ); } - @Test + @ProcessorTest public void shouldReverseMapIntegerSetToStringSet() { Target target = new Target(); - target.setAnotherStringSet( new HashSet( Arrays.asList( "1", "2" ) ) ); + target.setAnotherStringSet( new HashSet<>( Arrays.asList( "1", "2" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -186,10 +170,10 @@ public void shouldReverseMapIntegerSetToStringSet() { assertThat( source.getAnotherIntegerStream() ).containsOnly( 1, 2 ); } - @Test + @ProcessorTest public void shouldMapSetOfEnumToStringSet() { Source source = new Source(); - source.setColours( EnumSet.of( Colour.BLUE, Colour.GREEN ).stream() ); + source.setColours( Stream.of( Colour.BLUE, Colour.GREEN ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -197,10 +181,10 @@ public void shouldMapSetOfEnumToStringSet() { assertThat( target.getColours() ).containsOnly( "BLUE", "GREEN" ); } - @Test + @ProcessorTest public void shouldReverseMapSetOfEnumToStringSet() { Target target = new Target(); - target.setColours( new HashSet( Arrays.asList( "BLUE", "GREEN" ) ) ); + target.setColours( new HashSet<>( Arrays.asList( "BLUE", "GREEN" ) ) ); Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); @@ -208,19 +192,19 @@ public void shouldReverseMapSetOfEnumToStringSet() { assertThat( source.getColours() ).containsOnly( Colour.GREEN, Colour.BLUE ); } - @Test + @ProcessorTest public void shouldMapIntegerStreamToNumberSet() { Set numbers = SourceTargetMapper.INSTANCE - .integerStreamToNumberSet( Arrays.asList( 123, 456 ).stream() ); + .integerStreamToNumberSet( Stream.of( 123, 456 ) ); assertThat( numbers ).isNotNull(); assertThat( numbers ).containsOnly( 123, 456 ); } - @Test + @ProcessorTest public void shouldMapNonGenericList() { Source source = new Source(); - source.setStringStream3( new ArrayList( Arrays.asList( "Bob", "Alice" ) ).stream() ); + source.setStringStream3( new ArrayList<>( Arrays.asList( "Bob", "Alice" ) ).stream() ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); @@ -241,4 +225,74 @@ public void shouldMapNonGenericList() { assertThat( mappedSource ).isNotNull(); assertThat( mappedSource.getStringStream3() ).containsExactly( "Bill", "Bob" ); } + + @ProcessorTest + public void shouldMapIntegerToIntegerArray() { + Source source = new Source(); + source.setIntegerStream2( Stream.of( 1, 2 ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getIntegerArray() ).containsExactly( 1, 2 ); + } + + @ProcessorTest + public void shouldReverseIntegerToIntegerArray() { + Target target = new Target(); + target.setIntegerArray( new Integer[]{ 1, 2 } ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getIntegerStream2() ).containsExactly( 1, 2 ); + } + + @ProcessorTest + public void shouldMapIntegerArrayToIntegerMultiArray() { + Source source = new Source(); + source.setIntegerArrayStream( Stream.of( new Integer[]{ 1, 2 }, new Integer[]{ 2, 3 } ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getIntegerMultiArray() ) + .isDeepEqualTo( new Integer[][]{ new Integer[]{ 1, 2 }, new Integer[]{ 2, 3 } } ); + } + + @ProcessorTest + public void shouldReverseIntegerArrayToIntegerMultiArray() { + Target target = new Target(); + target.setIntegerMultiArray( new Integer[][]{ new Integer[]{ 1, 2 }, new Integer[]{ 2, 3 } } ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getIntegerArrayStream() ).containsExactly( new Integer[]{ 1, 2 }, new Integer[]{ 2, 3 } ); + } + + @ProcessorTest + public void shouldMapTypeWithGenericsToArrayWithGenerics() { + Source source = new Source(); + Comparable comparable = o -> 0; + source.setStreamWithGenerics( Stream.of( comparable ) ); + + Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getArrayWithGenerics() ).containsExactly( comparable ); + } + + @ProcessorTest + @SuppressWarnings("unchecked") + public void shouldReverseMapTypeWithGenericsToArrayWithGenerics() { + Target target = new Target(); + Comparable comparable = o -> 0; + target.setArrayWithGenerics( new Comparable[]{ comparable } ); + + Source source = SourceTargetMapper.INSTANCE.targetToSource( target ); + + assertThat( source ).isNotNull(); + assertThat( source.getStreamWithGenerics() ).containsExactly( comparable ); + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolder.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolder.java index 153c848fc8..d1fff8cbf5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolder.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolder.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; @@ -54,13 +41,10 @@ public boolean equals(Object obj) { } StringHolder other = (StringHolder) obj; if ( string == null ) { - if ( other.string != null ) { - return false; - } + return other.string == null; } - else if ( !string.equals( other.string ) ) { - return false; + else { + return string.equals( other.string ); } - return true; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolderArrayList.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolderArrayList.java index ccf8ed0299..3e98b0d569 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolderArrayList.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/StringHolderArrayList.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/Target.java index 29b338aa6d..91d9e89908 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; @@ -40,6 +27,12 @@ public class Target { private StringHolderArrayList nonGenericStringList; + private Integer[] integerArray; + + private Integer[][] integerMultiArray; + + private Comparable[] arrayWithGenerics; + public List getStringList() { return stringList; } @@ -90,7 +83,7 @@ public Set getColours() { public List getStringListNoSetter() { if ( stringListNoSetter == null ) { - stringListNoSetter = new ArrayList(); + stringListNoSetter = new ArrayList<>(); } return stringListNoSetter; } @@ -102,4 +95,28 @@ public StringHolderArrayList getNonGenericStringList() { public void setNonGenericStringList(StringHolderArrayList nonGenericStringList) { this.nonGenericStringList = nonGenericStringList; } + + public Integer[] getIntegerArray() { + return integerArray; + } + + public void setIntegerArray(Integer[] integerArray) { + this.integerArray = integerArray; + } + + public Integer[][] getIntegerMultiArray() { + return integerMultiArray; + } + + public void setIntegerMultiArray(Integer[][] integerMultiArray) { + this.integerMultiArray = integerMultiArray; + } + + public Comparable[] getArrayWithGenerics() { + return arrayWithGenerics; + } + + public void setArrayWithGenerics(Comparable[] arrayWithGenerics) { + this.arrayWithGenerics = arrayWithGenerics; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/TestList.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/TestList.java index 53617cddf0..fcdf4a5e8a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/TestList.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/TestList.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/MyCustomException.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/MyCustomException.java index 7e2a71fbe6..b0ebbfc60c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/MyCustomException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/MyCustomException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Source.java index a0deb021bb..3440d6f9e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/SourceElement.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/SourceElement.java index a0a95aecaa..0a7bc6ac16 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/SourceElement.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/SourceElement.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamMapper.java index 0b4b05e0f3..71a582845c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; @@ -34,8 +21,8 @@ public interface StreamMapper { StreamMapper INSTANCE = Mappers.getMapper( StreamMapper.class ); @Mappings( { - @Mapping( source = "stream", target = "targetStream"), - @Mapping( source = "sourceElements", target = "targetElements") + @Mapping(target = "targetStream", source = "stream"), + @Mapping(target = "targetElements", source = "sourceElements") } ) Target map(Source source); diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamsTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamsTest.java index b66f603267..027f619c98 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/StreamsTest.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; @@ -23,13 +10,11 @@ import java.util.TreeSet; import java.util.stream.Stream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.internal.util.Collections; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; @@ -38,7 +23,6 @@ * @author Filip Hrisafov */ @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Source.class, Target.class, @@ -49,36 +33,36 @@ }) public class StreamsTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test - public void shouldNotContainFunctionIdentity() throws Exception { + @ProcessorTest + public void shouldNotContainFunctionIdentity() { generatedSource.forMapper( StreamMapper.class ) .content() .as( "The Mapper implementation should not use Function.identity()" ) .doesNotContain( "Function.identity()" ); } - @Test - public void shouldMapSourceStream() throws Exception { + @ProcessorTest + public void shouldMapSourceStream() { List someInts = Arrays.asList( 1, 2, 3 ); Stream stream = someInts.stream(); Source source = new Source(); source.setStream( stream ); - source.setStringStream( Arrays.asList( "4", "5", "6", "7" ).stream() ); + source.setStringStream( Stream.of( "4", "5", "6", "7" ) ); source.setInts( Arrays.asList( 1, 2, 3 ) ); - source.setIntegerSet( Arrays.asList( 1, 1, 2, 2, 4, 4 ).stream() ); - source.setStringCollection( Arrays.asList( "1", "1", "2", "3" ).stream().distinct() ); - source.setIntegerIterable( Arrays.asList( 10, 11, 12 ).stream() ); - source.setSortedSet( Arrays.asList( 12, 11, 10 ).stream() ); - source.setNavigableSet( Arrays.asList( 12, 11, 10 ).stream() ); - source.setIntToStringStream( Arrays.asList( 10, 11, 12 ).stream() ); - source.setStringArrayStream( Arrays.asList( "4", "5", "6", "6" ).stream().limit( 2 ) ); + source.setIntegerSet( Stream.of( 1, 1, 2, 2, 4, 4 ) ); + source.setStringCollection( Stream.of( "1", "1", "2", "3" ).distinct() ); + source.setIntegerIterable( Stream.of( 10, 11, 12 ) ); + source.setSortedSet( Stream.of( 12, 11, 10 ) ); + source.setNavigableSet( Stream.of( 12, 11, 10 ) ); + source.setIntToStringStream( Stream.of( 10, 11, 12 ) ); + source.setStringArrayStream( Stream.of( "4", "5", "6", "6" ).limit( 2 ) ); SourceElement element = new SourceElement(); element.setSource( "source1" ); - source.setSourceElements( Arrays.asList( element ).stream() ); + source.setSourceElements( Stream.of( element ) ); Target target = StreamMapper.INSTANCE.map( source ); @@ -97,19 +81,19 @@ public void shouldMapSourceStream() throws Exception { assertThat( target.getTargetElements().get( 0 ).getSource() ).isEqualTo( "source1" ); } - @Test - public void shouldMapTargetStream() throws Exception { + @ProcessorTest + public void shouldMapTargetStream() { List someInts = Arrays.asList( 1, 2, 3 ); Stream stream = someInts.stream(); Target target = new Target(); target.setTargetStream( stream ); target.setStringStream( Arrays.asList( "4", "5", "6", "7" ) ); - target.setInts( Arrays.asList( 1, 2, 3 ).stream() ); + target.setInts( Stream.of( 1, 2, 3 ) ); target.setIntegerSet( Collections.asSet( 1, 1, 2, 2, 4, 4 ) ); target.setStringCollection( Collections.asSet( "1", "1", "2", "3" ) ); target.setIntegerIterable( Arrays.asList( 10, 11, 12 ) ); - target.setSortedSet( new TreeSet( Arrays.asList( 12, 11, 10 ) ) ); - target.setNavigableSet( new TreeSet( Arrays.asList( 12, 11, 10 ) ) ); + target.setSortedSet( new TreeSet<>( Arrays.asList( 12, 11, 10 ) ) ); + target.setNavigableSet( new TreeSet<>( Arrays.asList( 12, 11, 10 ) ) ); target.setIntToStringStream( Arrays.asList( "4", "5", "6" ) ); target.setStringArrayStream( new Integer[] { 10, 11, 12 } ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Target.java index babaf78a6f..6314c28bf2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/TargetElement.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/TargetElement.java index 4c0f647070..ed2e0877d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/TargetElement.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/base/TargetElement.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.base; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamContext.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamContext.java index 834abec16b..3b74c7c61a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamContext.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamContext.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextMapper.java index a98758a9e7..8a99db72dc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.context; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextTest.java index 78b705c890..74fbeb10b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/context/StreamWithContextTest.java @@ -1,32 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.context; -import java.util.Arrays; import java.util.Collection; import java.util.stream.Stream; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; @@ -35,29 +19,28 @@ */ @WithClasses({ StreamContext.class, StreamWithContextMapper.class }) @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class StreamWithContextTest { - @Test - public void shouldApplyAfterMapping() throws Exception { + @ProcessorTest + public void shouldApplyAfterMapping() { Stream stringStream = StreamWithContextMapper.INSTANCE.intStreamToStringStream( - Arrays.asList( 1, 2, 3, 5 ).stream() ); + Stream.of( 1, 2, 3, 5 ) ); assertThat( stringStream ).containsOnly( "1", "2" ); } - @Test - public void shouldApplyBeforeMappingOnArray() throws Exception { + @ProcessorTest + public void shouldApplyBeforeMappingOnArray() { Integer[] integers = new Integer[] { 1, 3 }; Stream stringStream = StreamWithContextMapper.INSTANCE.arrayToStream( integers ); assertThat( stringStream ).containsOnly( 30, 3 ); } - @Test - public void shouldApplyBeforeAndAfterMappingOnCollection() throws Exception { + @ProcessorTest + public void shouldApplyBeforeAndAfterMappingOnCollection() { Collection stringsStream = StreamWithContextMapper.INSTANCE.streamToCollection( - Arrays.asList( 10, 20, 40 ).stream() ); + Stream.of( 10, 20, 40 ) ); assertThat( stringsStream ).containsOnly( "23", "10", "20", "40", "230" ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/DefaultStreamImplementationTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/DefaultStreamImplementationTest.java index 21c4c997f4..8e69bafce2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/DefaultStreamImplementationTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/DefaultStreamImplementationTest.java @@ -1,27 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.List; @@ -31,11 +15,11 @@ import java.util.TreeSet; import java.util.stream.Stream; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Source.class, @@ -45,10 +29,9 @@ SourceTargetMapper.class }) @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class DefaultStreamImplementationTest { - @Test + @ProcessorTest public void shouldUseDefaultImplementationForNavigableSet() { NavigableSet target = SourceTargetMapper.INSTANCE.streamToNavigableSet( createSourceFooStream() ); @@ -57,7 +40,7 @@ public void shouldUseDefaultImplementationForNavigableSet() { assertThat( target ).isInstanceOf( TreeSet.class ); } - @Test + @ProcessorTest public void shouldUseDefaultImplementationForCollection() { Collection target = SourceTargetMapper.INSTANCE.streamToCollection( createSourceFooStream() ); @@ -66,7 +49,7 @@ public void shouldUseDefaultImplementationForCollection() { assertThat( target ).isInstanceOf( ArrayList.class ); } - @Test + @ProcessorTest public void shouldUseDefaultImplementationForIterable() { Iterable target = SourceTargetMapper.INSTANCE.streamToIterable( createSourceFooStream() ); @@ -75,7 +58,7 @@ public void shouldUseDefaultImplementationForIterable() { assertThat( target ).isInstanceOf( ArrayList.class ); } - @Test + @ProcessorTest public void shouldUseDefaultImplementationForList() { List target = SourceTargetMapper.INSTANCE.streamToList( createSourceFooStream() ); @@ -83,7 +66,7 @@ public void shouldUseDefaultImplementationForList() { assertThat( target ).isInstanceOf( ArrayList.class ); } - @Test + @ProcessorTest public void shouldUseDefaultImplementationForSet() { Set target = SourceTargetMapper.INSTANCE.streamToSet( createSourceFooStream() ); @@ -92,7 +75,7 @@ public void shouldUseDefaultImplementationForSet() { assertThat( target ).isInstanceOf( HashSet.class ); } - @Test + @ProcessorTest public void shouldUseDefaultImplementationForSortedSet() { SortedSet target = SourceTargetMapper.INSTANCE.streamToSortedSet( createSourceFooStream() ); @@ -101,9 +84,9 @@ public void shouldUseDefaultImplementationForSortedSet() { assertThat( target ).isInstanceOf( TreeSet.class ); } - @Test + @ProcessorTest public void shouldUseTargetParameterForMapping() { - List target = new ArrayList(); + List target = new ArrayList<>(); SourceTargetMapper.INSTANCE.sourceFoosToTargetFoosUsingTargetParameter( target, createSourceFooStream() @@ -112,7 +95,7 @@ public void shouldUseTargetParameterForMapping() { assertResultList( target ); } - @Test + @ProcessorTest public void shouldUseTargetParameterForArrayMapping() { TargetFoo[] target = new TargetFoo[3]; SourceTargetMapper.INSTANCE.streamToArrayUsingTargetParameter( @@ -124,7 +107,7 @@ public void shouldUseTargetParameterForArrayMapping() { assertThat( target ).containsOnly( new TargetFoo( "Bob" ), new TargetFoo( "Alice" ), null ); } - @Test + @ProcessorTest public void shouldUseTargetParameterForArrayMappingAndSmallerArray() { TargetFoo[] target = new TargetFoo[1]; SourceTargetMapper.INSTANCE.streamToArrayUsingTargetParameter( @@ -136,7 +119,7 @@ public void shouldUseTargetParameterForArrayMappingAndSmallerArray() { assertThat( target ).containsOnly( new TargetFoo( "Bob" ) ); } - @Test + @ProcessorTest public void shouldUseAndReturnTargetParameterForArrayMapping() { TargetFoo[] target = new TargetFoo[3]; TargetFoo[] result = @@ -147,7 +130,7 @@ public void shouldUseAndReturnTargetParameterForArrayMapping() { assertThat( target ).containsOnly( new TargetFoo( "Bob" ), new TargetFoo( "Alice" ), null ); } - @Test + @ProcessorTest public void shouldUseAndReturnTargetParameterForArrayMappingAndSmallerArray() { TargetFoo[] target = new TargetFoo[1]; TargetFoo[] result = @@ -158,9 +141,22 @@ public void shouldUseAndReturnTargetParameterForArrayMappingAndSmallerArray() { assertThat( target ).containsOnly( new TargetFoo( "Bob" ) ); } - @Test + @ProcessorTest + @IssueKey("1752") + public void shouldUseAndReturnTargetParameterArrayForNullSource() { + TargetFoo[] target = new TargetFoo[1]; + target[0] = new TargetFoo( "Bob" ); + TargetFoo[] result = + SourceTargetMapper.INSTANCE.streamToArrayUsingTargetParameterAndReturn( null, target ); + + assertThat( result ).isSameAs( target ); + assertThat( target ).isNotNull(); + assertThat( target ).containsOnly( new TargetFoo( "Bob" ) ); + } + + @ProcessorTest public void shouldUseAndReturnTargetParameterForMapping() { - List target = new ArrayList(); + List target = new ArrayList<>(); Iterable result = SourceTargetMapper.INSTANCE .sourceFoosToTargetFoosUsingTargetParameterAndReturn( createSourceFooStream(), target ); @@ -169,7 +165,21 @@ public void shouldUseAndReturnTargetParameterForMapping() { assertResultList( target ); } - @Test + @ProcessorTest + @IssueKey("1752") + public void shouldUseAndReturnTargetParameterForNullMapping() { + List target = new ArrayList<>(); + target.add( new TargetFoo( "Bob" ) ); + target.add( new TargetFoo( "Alice" ) ); + Iterable result = + SourceTargetMapper.INSTANCE + .sourceFoosToTargetFoosUsingTargetParameterAndReturn( null, target ); + + assertThat( result ).isSameAs( target ); + assertResultList( target ); + } + + @ProcessorTest public void shouldUseDefaultImplementationForListWithoutSetter() { Source source = new Source(); source.setFooStream( createSourceFooStream() ); @@ -185,6 +195,6 @@ private void assertResultList(Iterable fooIterable) { } private Stream createSourceFooStream() { - return Arrays.asList( new SourceFoo( "Bob" ), new SourceFoo( "Alice" ) ).stream(); + return Stream.of( new SourceFoo( "Bob" ), new SourceFoo( "Alice" ) ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterMapper.java index 392f84c4ca..3c9a21b672 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterSource.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterSource.java index 336a6572b8..0dd0bf6175 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterStreamMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterStreamMappingTest.java index 2966005cf7..f82a522bf5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterStreamMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterStreamMappingTest.java @@ -1,33 +1,18 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Arrays; import java.util.List; +import java.util.stream.Stream; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisfaov @@ -35,13 +20,12 @@ */ @WithClasses({ NoSetterMapper.class, NoSetterSource.class, NoSetterTarget.class }) @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class NoSetterStreamMappingTest { - @Test + @ProcessorTest public void compilesAndMapsCorrectly() { NoSetterSource source = new NoSetterSource(); - source.setListValues( Arrays.asList( "foo", "bar" ).stream() ); + source.setListValues( Stream.of( "foo", "bar" ) ); NoSetterTarget target = NoSetterMapper.INSTANCE.toTarget( source ); @@ -50,7 +34,7 @@ public void compilesAndMapsCorrectly() { // now test existing instances NoSetterSource source2 = new NoSetterSource(); - source2.setListValues( Arrays.asList( "baz" ).stream() ); + source2.setListValues( Stream.of( "baz" ) ); List originalCollectionInstance = target.getListValues(); NoSetterTarget target2 = NoSetterMapper.INSTANCE.toTargetWithExistingTarget( source2, target ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterTarget.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterTarget.java index 4de11a1d0e..7992012c81 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/NoSetterTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; @@ -26,7 +13,7 @@ * */ public class NoSetterTarget { - private List listValues = new ArrayList(); + private List listValues = new ArrayList<>(); public List getListValues() { return listValues; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Source.java index 33134f4c38..64e7424afc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceFoo.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceFoo.java index 9533f6cc29..7b1185d314 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceFoo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceFoo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceTargetMapper.java index c42f4997eb..b027dc9a0e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; @@ -35,7 +22,7 @@ public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - @Mapping(source = "fooStream", target = "fooListNoSetter") + @Mapping(target = "fooListNoSetter", source = "fooStream") Target sourceToTarget(Source source); TargetFoo sourceFooToTargetFoo(SourceFoo sourceFoo); diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Target.java index 98c366e427..2518414731 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; @@ -27,7 +14,7 @@ public class Target { public List getFooListNoSetter() { if ( fooListNoSetter == null ) { - fooListNoSetter = new ArrayList(); + fooListNoSetter = new ArrayList<>(); } return fooListNoSetter; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/TargetFoo.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/TargetFoo.java index 6e9f29ed53..10439fe2b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/TargetFoo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/defaultimplementation/TargetFoo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.defaultimplementation; @@ -58,14 +45,11 @@ public boolean equals(Object obj) { } TargetFoo other = (TargetFoo) obj; if ( name == null ) { - if ( other.name != null ) { - return false; - } + return other.name == null; } - else if ( !name.equals( other.name ) ) { - return false; + else { + return name.equals( other.name ); } - return true; } @Override diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/EmptyStreamMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/EmptyStreamMappingMapper.java index c74bb9403d..e47447dac4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/EmptyStreamMappingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/EmptyStreamMappingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFound.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFound.java index 31189594f5..d739fdb23b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFound.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFound.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFoundDisabledAuto.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFoundDisabledAuto.java index 157146ee92..a146f634d8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFoundDisabledAuto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousListToStreamNoElementMappingFoundDisabledAuto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamMappingTest.java index 7122e730e4..f3e540b7ca 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamMappingTest.java @@ -1,35 +1,20 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; import javax.tools.Diagnostic.Kind; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.NoProperties; import org.mapstruct.ap.test.WithProperties; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * Test for illegal mappings between collection/stream types, iterable and non-iterable types etc. @@ -44,88 +29,83 @@ * @author Filip Hrisafov */ @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class ErroneousStreamMappingTest { - @Test + @ProcessorTest @WithClasses({ ErroneousStreamToNonStreamMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousStreamToNonStreamMapper.class, kind = Kind.ERROR, - line = 28, - messageRegExp = "Can't generate mapping method from iterable type to non-iterable type"), + line = 15, + message = "Can't generate mapping method from iterable type from java stdlib to non-iterable type."), @Diagnostic(type = ErroneousStreamToNonStreamMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "Can't generate mapping method from non-iterable type to iterable type") + line = 17, + message = "Can't generate mapping method from non-iterable type to iterable type from java stdlib.") } ) public void shouldFailToGenerateImplementationBetweenStreamAndNonStreamOrIterable() { } - @Test + @ProcessorTest @WithClasses({ ErroneousStreamToPrimitivePropertyMapper.class, Source.class, Target.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousStreamToPrimitivePropertyMapper.class, kind = Kind.ERROR, - line = 26, - messageRegExp = - "Can't map property \"java.util.stream.Stream strings\" to \"int strings\". " - + - "Consider to declare/implement a mapping method: \"int map\\(java.util.stream.Stream" - + " value\\)\"") + line = 13, + message = "Can't map property \"Stream strings\" to \"int strings\". " + + "Consider to declare/implement a mapping method: \"int map(Stream value)\".") } ) public void shouldFailToGenerateImplementationBetweenCollectionAndPrimitive() { } - @Test + @ProcessorTest @WithClasses({ EmptyStreamMappingMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = EmptyStreamMappingMapper.class, kind = Kind.ERROR, - line = 36, - messageRegExp = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + line = 23, + message = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + "undefined in @IterableMapping, define at least one of them."), @Diagnostic(type = EmptyStreamMappingMapper.class, kind = Kind.ERROR, - line = 39, - messageRegExp = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + line = 26, + message = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + "undefined in @IterableMapping, define at least one of them."), @Diagnostic(type = EmptyStreamMappingMapper.class, kind = Kind.ERROR, - line = 42, - messageRegExp = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + line = 29, + message = "'nullValueMappingStrategy','dateformat', 'qualifiedBy' and 'elementTargetType' are " + "undefined in @IterableMapping, define at least one of them.") } ) public void shouldFailOnEmptyIterableAnnotationStreamMappings() { } - @Test + @ProcessorTest @WithClasses({ ErroneousStreamToStreamNoElementMappingFound.class, NoProperties.class, WithProperties.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousStreamToStreamNoElementMappingFound.class, kind = Kind.ERROR, - line = 37, - messageRegExp = "Can't map Stream element \".*WithProperties withProperties\" to \".*NoProperties " + - "noProperties\". Consider to declare/implement a mapping method: \".*NoProperties map\\(" + - ".*WithProperties value\\)") + line = 24, + message = "No target bean properties found: " + + "can't map Stream element \"WithProperties withProperties\" to \"NoProperties noProperties\". " + + "Consider to declare/implement a mapping method: \"NoProperties map(WithProperties value)\".") } ) public void shouldFailOnNoElementMappingFoundForStreamToStream() { } - @Test + @ProcessorTest @IssueKey("993") @WithClasses({ ErroneousStreamToStreamNoElementMappingFoundDisabledAuto.class }) @ExpectedCompilationOutcome( @@ -133,32 +113,31 @@ public void shouldFailOnNoElementMappingFoundForStreamToStream() { diagnostics = { @Diagnostic(type = ErroneousStreamToStreamNoElementMappingFoundDisabledAuto.class, kind = Kind.ERROR, - line = 32, - messageRegExp = "Can't map stream element \".*AttributedString\" to \".*String \". Consider to " + - "declare/implement a mapping method: \".*String map(.*AttributedString value)") + line = 19, + message = "Can't map stream element \"AttributedString\" to \"String \". " + + "Consider to declare/implement a mapping method: \"String map(AttributedString value)\".") } ) public void shouldFailOnNoElementMappingFoundForStreamToStreamWithDisabledAuto() { } - @Test + @ProcessorTest @WithClasses({ ErroneousListToStreamNoElementMappingFound.class, NoProperties.class, WithProperties.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousListToStreamNoElementMappingFound.class, kind = Kind.ERROR, - line = 38, - messageRegExp = - "Can't map Stream element \".*WithProperties withProperties\" to \".*NoProperties noProperties\"." + - " Consider to declare/implement a mapping method: \".*NoProperties map\\(.*WithProperties " + - "value\\)") + line = 25, + message = "No target bean properties found: " + + "can't map Stream element \"WithProperties withProperties\" to \"NoProperties noProperties\". " + + "Consider to declare/implement a mapping method: \"NoProperties map(WithProperties value)\".") } ) public void shouldFailOnNoElementMappingFoundForListToStream() { } - @Test + @ProcessorTest @IssueKey("993") @WithClasses({ ErroneousListToStreamNoElementMappingFoundDisabledAuto.class }) @ExpectedCompilationOutcome( @@ -166,31 +145,31 @@ public void shouldFailOnNoElementMappingFoundForListToStream() { diagnostics = { @Diagnostic(type = ErroneousListToStreamNoElementMappingFoundDisabledAuto.class, kind = Kind.ERROR, - line = 33, - messageRegExp = "Can't map stream element \".*AttributedString\" to \".*String \". Consider to " + - "declare/implement a mapping method: \".*String map\\(.*AttributedString value\\)") + line = 20, + message = "Can't map stream element \"AttributedString\" to \"String \". " + + "Consider to declare/implement a mapping method: \"String map(AttributedString value)\".") } ) public void shouldFailOnNoElementMappingFoundForListToStreamWithDisabledAuto() { } - @Test + @ProcessorTest @WithClasses({ ErroneousStreamToListNoElementMappingFound.class, NoProperties.class, WithProperties.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousStreamToListNoElementMappingFound.class, kind = Kind.ERROR, - line = 38, - messageRegExp = - "Can't map Stream element \".*WithProperties withProperties\" to .*NoProperties noProperties\"." + - " Consider to declare/implement a mapping method: \".*NoProperties map(.*WithProperties value)") + line = 25, + message = "No target bean properties found: " + + "can't map Stream element \"WithProperties withProperties\" to \"NoProperties noProperties\". " + + "Consider to declare/implement a mapping method: \"NoProperties map(WithProperties value)\".") } ) public void shouldFailOnNoElementMappingFoundForStreamToList() { } - @Test + @ProcessorTest @IssueKey("993") @WithClasses({ ErroneousStreamToListNoElementMappingFoundDisabledAuto.class }) @ExpectedCompilationOutcome( @@ -198,9 +177,9 @@ public void shouldFailOnNoElementMappingFoundForStreamToList() { diagnostics = { @Diagnostic(type = ErroneousStreamToListNoElementMappingFoundDisabledAuto.class, kind = Kind.ERROR, - line = 33, - messageRegExp = "Can't map stream element \".*AttributedString\" to .*String \". Consider to " + - "declare/implement a mapping method: \".*String map(.*AttributedString value)") + line = 20, + message = "Can't map stream element \"AttributedString\" to \"String \". " + + "Consider to declare/implement a mapping method: \"String map(AttributedString value)\".") } ) public void shouldFailOnNoElementMappingFoundForStreamToListWithDisabledAuto() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFound.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFound.java index 8fd1b67e13..68a3d46b76 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFound.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFound.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFoundDisabledAuto.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFoundDisabledAuto.java index a3c1c7e65c..ad025fc30d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFoundDisabledAuto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToListNoElementMappingFoundDisabledAuto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToNonStreamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToNonStreamMapper.java index a1607d9c7b..99679de6b5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToNonStreamMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToNonStreamMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToPrimitivePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToPrimitivePropertyMapper.java index 73ca458ee6..0a00518423 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToPrimitivePropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToPrimitivePropertyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFound.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFound.java index ac5d28a7a0..92da773868 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFound.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFound.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFoundDisabledAuto.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFoundDisabledAuto.java index 56efd7e330..82df9117ef 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFoundDisabledAuto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/ErroneousStreamToStreamNoElementMappingFoundDisabledAuto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Source.java index d85c7ea7d5..09af31f3ad 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Target.java index ae5ae0b709..54cc350d36 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/erroneous/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.erroneous; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Bar.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Bar.java index 15e24a728b..9aca654647 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Bar.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Bar.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamSource.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamSource.java index da2d603a7e..d6c4c4a7b2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamTarget.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamTarget.java index 50d5c1bbdc..696fab515a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousNonMappableStreamTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousStreamNonMappableStreamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousStreamNonMappableStreamMapper.java index e36f78376b..ed5c9e494d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousStreamNonMappableStreamMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ErroneousStreamNonMappableStreamMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Foo.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Foo.java index fb80ee460a..d4465cd126 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Foo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Foo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ForgedStreamMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ForgedStreamMappingTest.java index 16f8379429..2ad882891f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ForgedStreamMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/ForgedStreamMappingTest.java @@ -1,52 +1,36 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; -import static org.assertj.core.api.Assertions.assertThat; - import javax.tools.Diagnostic.Kind; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.internal.util.Collections; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * Test for mappings between collection and stream types, * * @author Filip Hrisafov */ @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class ForgedStreamMappingTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @WithClasses({ StreamMapper.class, Source.class, Target.class }) public void shouldForgeNewIterableMappingMethod() { @@ -69,7 +53,7 @@ public void shouldForgeNewIterableMappingMethod() { .doesNotContain( "Stream.empty()" ); } - @Test + @ProcessorTest @WithClasses({ ErroneousStreamNonMappableStreamMapper.class, ErroneousNonMappableStreamSource.class, @@ -82,15 +66,16 @@ public void shouldForgeNewIterableMappingMethod() { diagnostics = { @Diagnostic(type = ErroneousStreamNonMappableStreamMapper.class, kind = Kind.ERROR, - line = 30, - messageRegExp = "Can't map Stream element \".* nonMappableStream\" to \".* nonMappableStream\". " - + "Consider to declare/implement a mapping method: .*."), + line = 17, + message = "No target bean properties found: " + + "can't map Stream element \"Foo nonMappableStream\" to \"Bar nonMappableStream\". " + + "Consider to declare/implement a mapping method: \"Bar map(Foo value)\".") } ) public void shouldGenerateNonMappableMethodForSetMapping() { } - @Test + @ProcessorTest @WithClasses({ StreamMapper.class, Source.class, Target.class }) public void shouldForgeNewIterableMappingMethodReturnNullOnNullSource() { @@ -108,7 +93,7 @@ public void shouldForgeNewIterableMappingMethodReturnNullOnNullSource() { assertThat( source2.getFooStream3() ).isNull(); } - @Test + @ProcessorTest @WithClasses({ StreamMapperNullValueMappingReturnDefault.class, Source.class, Target.class }) public void shouldForgeNewIterableMappingMethodReturnEmptyOnNullSource() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Source.java index 47ec385886..5c08dad04a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapper.java index 61692c16e3..881f7f6f34 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapperNullValueMappingReturnDefault.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapperNullValueMappingReturnDefault.java index 13a0757c0f..f277ff0829 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapperNullValueMappingReturnDefault.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/StreamMapperNullValueMappingReturnDefault.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Target.java index 02bee8ea84..407b34977c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/forged/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.forged; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Source.java index a4136a8ee9..d3e594da74 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.streamtononiterable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/SourceTargetMapper.java index f83d2a03cd..5653cf0065 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.streamtononiterable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StreamToNonIterableMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StreamToNonIterableMappingTest.java index f877b5536e..26c8e88324 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StreamToNonIterableMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StreamToNonIterableMappingTest.java @@ -1,49 +1,33 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.streamtononiterable; -import static org.assertj.core.api.Assertions.assertThat; - -import java.util.Arrays; +import java.util.stream.Stream; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; @WithClasses({ Source.class, Target.class, SourceTargetMapper.class, StringListMapper.class }) @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class StreamToNonIterableMappingTest { - @Test + @ProcessorTest public void shouldMapStringStreamToStringUsingCustomMapper() { Source source = new Source(); - source.setNames( Arrays.asList( "Alice", "Bob", "Jim" ).stream() ); + source.setNames( Stream.of( "Alice", "Bob", "Jim" ) ); Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source ); assertThat( target ).isNotNull(); assertThat( target.getNames() ).isEqualTo( "Alice-Bob-Jim" ); } - @Test + @ProcessorTest public void shouldReverseMapStringStreamToStringUsingCustomMapper() { Target target = new Target(); target.setNames( "Alice-Bob-Jim" ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StringListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StringListMapper.java index f8bbc79ec2..f8da66374e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StringListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/StringListMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.streamtononiterable; @@ -29,6 +16,6 @@ public String stringListToString(Stream strings) { } public Stream stringToStringList(String string) { - return string == null ? null : Arrays.asList( string.split( "-" ) ).stream(); + return string == null ? null : Arrays.stream( string.split( "-" ) ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Target.java index a0593d4b68..a2380f0ba5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/streamtononiterable/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.streamtononiterable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableExtendsBoundTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableExtendsBoundTargetMapper.java index 77d368a9e8..5eb7c4a6e1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableExtendsBoundTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableExtendsBoundTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableSuperBoundSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableSuperBoundSourceMapper.java index 24340bf49f..1058269929 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableSuperBoundSourceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableSuperBoundSourceMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java index fb1008a709..add2dfbfff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java index d32637dcfc..ff684af6fb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ErroneousIterableTypeVarBoundMapperOnMethod.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSource.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSource.java index 9235fb726c..8a7f6e2aa2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSourceTargetMapper.java index e5c9e6d9e0..d896e65b49 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/ExtendsBoundSourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Idea.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Idea.java index e3e42c0984..063a5e5615 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Idea.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Idea.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; @@ -24,4 +11,13 @@ */ public class Idea { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Plan.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Plan.java index 15b28ff2f4..7aa366ec95 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Plan.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Plan.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; @@ -24,4 +11,13 @@ */ public class Plan { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Source.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Source.java index 02f08a9e1c..4aea62255b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SourceSuperBoundTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SourceSuperBoundTargetMapper.java index 6704dbfa99..f33027b2e6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SourceSuperBoundTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SourceSuperBoundTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SuperBoundTarget.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SuperBoundTarget.java index 7d30efceab..5ab829f602 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SuperBoundTarget.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/SuperBoundTarget.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Target.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Target.java index b657985bd8..b70ab2eeb5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; diff --git a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/WildCardTest.java b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/WildCardTest.java index 67db736ac8..a039951495 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/WildCardTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/java8stream/wildcard/WildCardTest.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.java8stream.wildcard; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Filip Hrisafov */ @IssueKey("962") -@RunWith(AnnotationProcessorTestRunner.class) public class WildCardTest { - @Test + @ProcessorTest @WithClasses({ ExtendsBoundSourceTargetMapper.class, ExtendsBoundSource.class, @@ -56,7 +40,7 @@ public void shouldGenerateExtendsBoundSourceForgedStreamMethod() { } - @Test + @ProcessorTest @WithClasses({ SourceSuperBoundTargetMapper.class, Source.class, @@ -76,57 +60,57 @@ public void shouldGenerateSuperBoundTargetForgedIterableMethod() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableSuperBoundSourceMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousIterableSuperBoundSourceMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 34, - messageRegExp = "Can't generate mapping method for a wildcard super bound source.") + line = 21, + message = "Can't generate mapping method for a wildcard super bound source.") } ) public void shouldFailOnSuperBoundSource() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableExtendsBoundTargetMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousIterableExtendsBoundTargetMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 34, - messageRegExp = "Can't generate mapping method for a wildcard extends bound result.") + line = 21, + message = "Can't generate mapping method for a wildcard extends bound result.") } ) public void shouldFailOnExtendsBoundTarget() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableTypeVarBoundMapperOnMethod.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousIterableTypeVarBoundMapperOnMethod.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 34, - messageRegExp = "Can't generate mapping method for a generic type variable target.") + line = 21, + message = "Can't generate mapping method for a generic type variable target.") } ) public void shouldFailOnTypeVarSource() { } - @Test + @ProcessorTest @WithClasses({ ErroneousIterableTypeVarBoundMapperOnMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousIterableTypeVarBoundMapperOnMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 34, - messageRegExp = "Can't generate mapping method for a generic type variable source.") + line = 21, + message = "Can't generate mapping method for a generic type variable source.") } ) public void shouldFailOnTypeVarTarget() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/javadoc/ErroneousJavadocMapper.java b/processor/src/test/java/org/mapstruct/ap/test/javadoc/ErroneousJavadocMapper.java new file mode 100644 index 0000000000..39f6da2890 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/javadoc/ErroneousJavadocMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.javadoc; + +import org.mapstruct.Javadoc; +import org.mapstruct.Mapper; + +/** + * @author Jose Carlos Campanero Ortiz + */ +@Mapper +@Javadoc +public interface ErroneousJavadocMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocAnnotatedWithAttributesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocAnnotatedWithAttributesMapper.java new file mode 100644 index 0000000000..eb6285ff13 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocAnnotatedWithAttributesMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.javadoc; + +import org.mapstruct.Javadoc; +import org.mapstruct.Mapper; + +@Mapper +@Javadoc( + value = "This is the description", + authors = { "author1", "author2" }, + deprecated = "Use {@link OtherMapper} instead", + since = "0.1" +) +@Deprecated +public interface JavadocAnnotatedWithAttributesMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocAnnotatedWithValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocAnnotatedWithValueMapper.java new file mode 100644 index 0000000000..150d7e5f76 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocAnnotatedWithValueMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.javadoc; + +import org.mapstruct.Javadoc; +import org.mapstruct.Mapper; + +@Mapper +@Javadoc("This is the description\n" + + "\n" + + "@author author1\n" + + "@author author2\n" + + "\n" + + "@deprecated Use {@link OtherMapper} instead\n" + + "@since 0.1\n") +@Deprecated +public interface JavadocAnnotatedWithValueMapper { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocTest.java b/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocTest.java new file mode 100644 index 0000000000..316114389f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/javadoc/JavadocTest.java @@ -0,0 +1,54 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.javadoc; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +/** + * @author Jose Carlos Campanero Ortiz + */ +@IssueKey("2987") +class JavadocTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses( { JavadocAnnotatedWithValueMapper.class } ) + void javadocAnnotatedWithValueMapper() { + generatedSource.addComparisonToFixtureFor( JavadocAnnotatedWithValueMapper.class ); + } + + @ProcessorTest + @WithClasses( { JavadocAnnotatedWithAttributesMapper.class } ) + void javadocAnnotatedWithAttributesMapper() { + generatedSource.addComparisonToFixtureFor( JavadocAnnotatedWithAttributesMapper.class ); + } + + @ProcessorTest + @IssueKey("2987") + @WithClasses({ ErroneousJavadocMapper.class }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousJavadocMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 15, + message = "'value', 'authors', 'deprecated' and 'since' are undefined in @Javadoc, " + + "define at least one of them.") + } + ) + void shouldFailOnEmptyJavadocAnnotation() { + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/AllDefaultsProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/AllDefaultsProperty.kt new file mode 100644 index 0000000000..e452102f6e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/AllDefaultsProperty.kt @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class AllDefaultsProperty(val firstName: String? = null, val lastName: String? = null) diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/AllDefaultsPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/AllDefaultsPropertyMapper.java new file mode 100644 index 0000000000..1f8aab4624 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/AllDefaultsPropertyMapper.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface AllDefaultsPropertyMapper { + + AllDefaultsPropertyMapper INSTANCE = Mappers.getMapper( AllDefaultsPropertyMapper.class ); + + AllDefaultsProperty map(Source source); + + class Source { + + private final String firstName; + private final String lastName; + + public Source(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerDto.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerDto.kt new file mode 100644 index 0000000000..3fbd48b0b1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerDto.kt @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class CustomerDto(var name: String?, var email: String?) diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerEntity.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerEntity.java new file mode 100644 index 0000000000..7ddd41bda0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerEntity.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +/** + * @author Filip Hrisafov + */ +public class CustomerEntity { + + private String name; + private String mail; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getMail() { + return mail; + } + + public void setMail(String mail) { + this.mail = mail; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerMapper.java new file mode 100644 index 0000000000..1830a9c583 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/CustomerMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "mail", source = "email") + CustomerEntity fromData(CustomerDto record); + + @InheritInverseConfiguration + CustomerDto toData(CustomerEntity entity); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/Default.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/Default.kt new file mode 100644 index 0000000000..58ebbd128d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/Default.kt @@ -0,0 +1,10 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +@Target(AnnotationTarget.CONSTRUCTOR) +@Retention(AnnotationRetention.BINARY) +annotation class Default diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/DefaultProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/DefaultProperty.kt new file mode 100644 index 0000000000..f5ff27d3d3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/DefaultProperty.kt @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class DefaultPropertySource(val default: Boolean, val identifier: String?) + +class DefaultPropertyTarget( + var default: Boolean, + var identifier: String? +) diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/DefaultPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/DefaultPropertyMapper.java new file mode 100644 index 0000000000..ce08e26e7e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/DefaultPropertyMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface DefaultPropertyMapper { + + DefaultPropertyMapper INSTANCE = Mappers.getMapper( DefaultPropertyMapper.class ); + + DefaultPropertyTarget map(DefaultPropertySource source); + + DefaultPropertySource map(DefaultPropertyTarget target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/KotlinDataTest.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/KotlinDataTest.java new file mode 100644 index 0000000000..94d0d90d75 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/KotlinDataTest.java @@ -0,0 +1,521 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.junit.jupiter.api.Nested; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithKotlin; +import org.mapstruct.ap.testutil.WithKotlinSources; +import org.mapstruct.ap.testutil.WithTestDependency; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +class KotlinDataTest { + + @Nested + @WithClasses({ + CustomerEntity.class, + CustomerMapper.class + }) + @WithKotlinSources("CustomerDto.kt") + class Standard { + + @ProcessorTest + void shouldMapData() { + CustomerEntity customer = CustomerMapper.INSTANCE.fromData( new CustomerDto( + "Kermit", + "kermit@test.com" + ) ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getMail() ).isEqualTo( "kermit@test.com" ); + } + + @ProcessorTest + void shouldMapIntoData() { + CustomerEntity entity = new CustomerEntity(); + entity.setName( "Kermit" ); + entity.setMail( "kermit@test.com" ); + + CustomerDto customer = CustomerMapper.INSTANCE.toData( entity ); + + assertThat( customer ).isNotNull(); + assertThat( customer.getName() ).isEqualTo( "Kermit" ); + assertThat( customer.getEmail() ).isEqualTo( "kermit@test.com" ); + } + + } + + @Nested + @WithClasses({ + SinglePropertyMapper.class, + }) + @WithKotlinSources("SingleProperty.kt") + class SingleData { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + + SingleProperty property = SinglePropertyMapper.INSTANCE.map( new SinglePropertyMapper.Source( "test" ) ); + assertThat( property ).isNotNull(); + assertThat( property.getValue() ).isEqualTo( "test" ); + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + type = SinglePropertyMapper.class, + line = 19, + message = "Unmapped target property: \"copy\"." + ) + } + ) + void shouldCompileWithWarnings() { + + SingleProperty property = SinglePropertyMapper.INSTANCE.map( new SinglePropertyMapper.Source( "test" ) ); + assertThat( property ).isNotNull(); + assertThat( property.getValue() ).isEqualTo( "test" ); + } + } + + @Nested + @WithClasses({ + AllDefaultsPropertyMapper.class, + }) + @WithKotlinSources("AllDefaultsProperty.kt") + class AllDefaults { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + + AllDefaultsProperty property = AllDefaultsPropertyMapper.INSTANCE.map( new AllDefaultsPropertyMapper.Source( + "Kermit", + "the Frog" + ) ); + assertThat( property ).isNotNull(); + assertThat( property.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( property.getLastName() ).isEqualTo( "the Frog" ); + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + type = AllDefaultsPropertyMapper.class, + line = 19, + message = "No target property found for target \"AllDefaultsProperty\"." + ) + } + ) + void shouldCompileWithWarnings() { + + AllDefaultsProperty property = AllDefaultsPropertyMapper.INSTANCE.map( new AllDefaultsPropertyMapper.Source( + "Kermit", + "the Frog" + ) ); + assertThat( property ).isNotNull(); + assertThat( property.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( property.getLastName() ).isEqualTo( "the Frog" ); + } + } + + @Nested + @WithClasses({ + MultiConstructorPropertyMapper.class, + }) + @WithKotlinSources("MultiConstructorProperty.kt") + class MultiConstructor { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + + MultiConstructorProperty property = MultiConstructorPropertyMapper.INSTANCE + .map( new MultiConstructorPropertyMapper.Source( + "Kermit", + "the Frog", + "Kermit the Frog" + ) ); + assertThat( property ).isNotNull(); + assertThat( property.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( property.getLastName() ).isEqualTo( "the Frog" ); + assertThat( property.getDisplayName() ).isEqualTo( "Kermit the Frog" ); + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiConstructorPropertyMapper.class, + line = 19, + messageRegExp = "Ambiguous constructors found for creating .*MultiConstructorProperty: " + + "MultiConstructorProperty\\(java.lang.String, java.lang.String.*\\), " + + "MultiConstructorProperty\\(java.lang.String, java.lang.String.*\\)\\. " + + "Either declare parameterless constructor or annotate the default constructor with an " + + "annotation named @Default\\." + ) + } + ) + void shouldFailToCompile() { + + } + } + + @Nested + @WithClasses({ + MultiSimilarConstructorPropertyMapper.class, + }) + @WithKotlinSources("MultiSimilarConstructorProperty.kt") + class MultiSimilarConstructor { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + PrimaryString primaryString = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + "Kermit the Frog" + ); + assertThat( primaryString ).isNotNull(); + assertThat( primaryString.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryString.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryString.getDisplayName() ).isEqualTo( "Kermit the Frog" ); + + PrimaryInt primaryInt = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + 42 + ); + assertThat( primaryInt ).isNotNull(); + assertThat( primaryInt.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryInt.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryInt.getAge() ).isEqualTo( 42 ); + + PrimaryLong primaryLong = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + 42L + ); + assertThat( primaryLong ).isNotNull(); + assertThat( primaryLong.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryLong.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryLong.getAge() ).isEqualTo( 42 ); + + PrimaryBoolean primaryBoolean = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + true + ); + assertThat( primaryBoolean ).isNotNull(); + assertThat( primaryBoolean.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryBoolean.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryBoolean.getActive() ).isTrue(); + + PrimaryByte primaryByte = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + (byte) 4 + ); + assertThat( primaryByte ).isNotNull(); + assertThat( primaryByte.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryByte.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryByte.getB() ).isEqualTo( (byte) 4 ); + + PrimaryShort primaryShort = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + (short) 4 + ); + assertThat( primaryShort ).isNotNull(); + assertThat( primaryShort.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryShort.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryShort.getAge() ).isEqualTo( (short) 4 ); + + PrimaryChar primaryChar = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + 't' + ); + assertThat( primaryChar ).isNotNull(); + assertThat( primaryChar.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryChar.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryChar.getC() ).isEqualTo( 't' ); + + PrimaryFloat primaryFloat = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + 42.2f + ); + assertThat( primaryFloat ).isNotNull(); + assertThat( primaryFloat.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryFloat.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryFloat.getPrice() ).isEqualTo( 42.2f ); + + PrimaryDouble primaryDouble = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + 42.2 + ); + assertThat( primaryDouble ).isNotNull(); + assertThat( primaryDouble.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryDouble.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryDouble.getPrice() ).isEqualTo( 42.2d ); + + PrimaryArray primaryArray = MultiSimilarConstructorPropertyMapper.INSTANCE.map( + new MultiSimilarConstructorPropertyMapper.Source( + "Kermit", + "the Frog" + ), + new String[] { "Kermit", "the Frog" } + ); + assertThat( primaryArray ).isNotNull(); + assertThat( primaryArray.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( primaryArray.getLastName() ).isEqualTo( "the Frog" ); + assertThat( primaryArray.getElements() ).containsExactly( "Kermit", "the Frog" ); + } + + @ProcessorTest + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 19, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryString" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 21, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryInt" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 23, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryLong" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 25, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryBoolean" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 27, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryByte" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 29, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryShort" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 31, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryChar" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 33, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryFloat" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 35, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryDouble" + ), + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.ERROR, + type = MultiSimilarConstructorPropertyMapper.class, + line = 37, + messageRegExp = "Ambiguous constructors found for creating .*PrimaryArray" + ) + + + } + ) + void shouldFailToCompile() { + + } + } + + @Nested + @WithClasses({ + MultiDefaultConstructorPropertyMapper.class, + }) + @WithKotlinSources({ + "MultiDefaultConstructorProperty.kt", + "Default.kt" + }) + class MultiDefaultConstructor { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + + MultiDefaultConstructorProperty property = MultiDefaultConstructorPropertyMapper.INSTANCE + .map( new MultiDefaultConstructorPropertyMapper.Source( + "Kermit", + "the Frog", + "Kermit the Frog" + ) ); + assertThat( property ).isNotNull(); + assertThat( property.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( property.getLastName() ).isEqualTo( "the Frog" ); + assertThat( property.getDisplayName() ).isNull(); + } + + @ProcessorTest + void shouldCompileWithoutKotlin() { + MultiDefaultConstructorProperty property = MultiDefaultConstructorPropertyMapper.INSTANCE + .map( new MultiDefaultConstructorPropertyMapper.Source( + "Kermit", + "the Frog", + "Kermit the Frog" + ) ); + assertThat( property ).isNotNull(); + assertThat( property.getFirstName() ).isEqualTo( "Kermit" ); + assertThat( property.getLastName() ).isEqualTo( "the Frog" ); + assertThat( property.getDisplayName() ).isNull(); + } + } + + @Nested + @WithClasses({ + UnsignedPropertyMapper.class, + }) + @WithKotlinSources("UnsignedProperty.kt") + class Unsigned { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + + UnsignedProperty property = UnsignedPropertyMapper.INSTANCE.map( new UnsignedPropertyMapper.Source( 10 ) ); + assertThat( property ).isNotNull(); + assertThat( property.getAge() ).isEqualTo( 10 ); + + UnsignedPropertyMapper.Source source = UnsignedPropertyMapper.INSTANCE.map( new UnsignedProperty( 20 ) ); + assertThat( source ).isNotNull(); + assertThat( source.getAge() ).isEqualTo( 20 ); + } + + @ProcessorTest + @WithTestDependency( "kotlin-stdlib" ) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic( + kind = javax.tools.Diagnostic.Kind.WARNING, + type = UnsignedPropertyMapper.class, + line = 19, + messageRegExp = "Unmapped target property: \"copy-.*\"\\." + ) + } + ) + void shouldCompileWithoutKotlinJvmMetadata() { + UnsignedProperty property = UnsignedPropertyMapper.INSTANCE.map( new UnsignedPropertyMapper.Source( 10 ) ); + assertThat( property ).isNotNull(); + assertThat( property.getAge() ).isEqualTo( 10 ); + + UnsignedPropertyMapper.Source source = UnsignedPropertyMapper.INSTANCE.map( new UnsignedProperty( 20 ) ); + assertThat( source ).isNotNull(); + assertThat( source.getAge() ).isEqualTo( 20 ); + } + } + + @Nested + @WithClasses({ + DefaultPropertyMapper.class, + }) + @WithKotlinSources("DefaultProperty.kt") + class Default { + + @ProcessorTest + @WithKotlin + void shouldCompileWithoutWarnings() { + + DefaultPropertyTarget target = DefaultPropertyMapper.INSTANCE.map( new DefaultPropertySource( + true, + "test" + ) ); + assertThat( target ).isNotNull(); + assertThat( target.getDefault() ).isTrue(); + assertThat( target.getIdentifier() ).isEqualTo( "test" ); + + DefaultPropertySource source = DefaultPropertyMapper.INSTANCE.map( new DefaultPropertyTarget( + false, + "private" + ) ); + assertThat( source ).isNotNull(); + assertThat( source.getDefault() ).isFalse(); + assertThat( source.getIdentifier() ).isEqualTo( "private" ); + + } + + @ProcessorTest + void shouldCompileWithoutKotlin() { + DefaultPropertyTarget target = DefaultPropertyMapper.INSTANCE.map( new DefaultPropertySource( + true, + "test" + ) ); + assertThat( target ).isNotNull(); + assertThat( target.getDefault() ).isTrue(); + assertThat( target.getIdentifier() ).isEqualTo( "test" ); + + DefaultPropertySource source = DefaultPropertyMapper.INSTANCE.map( new DefaultPropertyTarget( + false, + "private" + ) ); + assertThat( source ).isNotNull(); + assertThat( source.getDefault() ).isFalse(); + assertThat( source.getIdentifier() ).isEqualTo( "private" ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiConstructorProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiConstructorProperty.kt new file mode 100644 index 0000000000..46cb8034e9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiConstructorProperty.kt @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class MultiConstructorProperty(var firstName: String?, var lastName: String?, var displayName: String?) { + constructor(firstName: String?, lastName: String?) : this(firstName, lastName, null) +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiConstructorPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiConstructorPropertyMapper.java new file mode 100644 index 0000000000..3186226a57 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiConstructorPropertyMapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface MultiConstructorPropertyMapper { + + MultiConstructorPropertyMapper INSTANCE = Mappers.getMapper( MultiConstructorPropertyMapper.class ); + + MultiConstructorProperty map(Source source); + + class Source { + + private final String firstName; + private final String lastName; + private final String displayName; + + public Source(String firstName, String lastName, String displayName) { + this.firstName = firstName; + this.lastName = lastName; + this.displayName = displayName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public String getDisplayName() { + return displayName; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiDefaultConstructorProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiDefaultConstructorProperty.kt new file mode 100644 index 0000000000..9f9af16053 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiDefaultConstructorProperty.kt @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class MultiDefaultConstructorProperty(val firstName: String?, val lastName: String?, val displayName: String?) { + @Default + constructor(firstName: String?, lastName: String?) : this(firstName, lastName, null) +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiDefaultConstructorPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiDefaultConstructorPropertyMapper.java new file mode 100644 index 0000000000..da04c01fb8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiDefaultConstructorPropertyMapper.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface MultiDefaultConstructorPropertyMapper { + + MultiDefaultConstructorPropertyMapper INSTANCE = Mappers.getMapper( MultiDefaultConstructorPropertyMapper.class ); + + MultiDefaultConstructorProperty map(Source source); + + class Source { + + private final String firstName; + private final String lastName; + private final String displayName; + + public Source(String firstName, String lastName, String displayName) { + this.firstName = firstName; + this.lastName = lastName; + this.displayName = displayName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + + public String getDisplayName() { + return displayName; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiSimilarConstructorProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiSimilarConstructorProperty.kt new file mode 100644 index 0000000000..e122169075 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiSimilarConstructorProperty.kt @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class PrimaryString(var firstName: String?, var lastName: String?, var displayName: String?) { + constructor(firstName: String?, lastName: String?, age: Int) : this(firstName, lastName, null as String?) +} + +data class PrimaryInt(var firstName: String?, var lastName: String?, var age: Int) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, -1) +} + +data class PrimaryLong(var firstName: String?, var lastName: String?, var age: Long) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, -1) +} + +data class PrimaryBoolean(var firstName: String?, var lastName: String?, var active: Boolean) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, false) +} + +data class PrimaryByte(var firstName: String?, var lastName: String?, var b: Byte) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, 0) +} + +data class PrimaryShort(var firstName: String?, var lastName: String?, var age: Short) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, 0) +} + +data class PrimaryChar(var firstName: String?, var lastName: String?, var c: Char) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, 'a') +} + +data class PrimaryFloat(var firstName: String?, var lastName: String?, var price: Float) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, 0.0f) +} + +data class PrimaryDouble(var firstName: String?, var lastName: String?, var price: Double) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, 0.0) +} + +@Suppress("ArrayInDataClass") +data class PrimaryArray(var firstName: String?, var lastName: String?, var elements: Array) { + constructor(firstName: String?, lastName: String?, displayName: String?) : this(firstName, lastName, emptyArray()) +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiSimilarConstructorPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiSimilarConstructorPropertyMapper.java new file mode 100644 index 0000000000..86021cd6d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/MultiSimilarConstructorPropertyMapper.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface MultiSimilarConstructorPropertyMapper { + + MultiSimilarConstructorPropertyMapper INSTANCE = Mappers.getMapper( MultiSimilarConstructorPropertyMapper.class ); + + PrimaryString map(Source source, String displayName); + + PrimaryInt map(Source source, int age); + + PrimaryLong map(Source source, long age); + + PrimaryBoolean map(Source source, boolean active); + + PrimaryByte map(Source source, byte b); + + PrimaryShort map(Source source, short age); + + PrimaryChar map(Source source, char c); + + PrimaryFloat map(Source source, float price); + + PrimaryDouble map(Source source, double price); + + PrimaryArray map(Source source, String[] elements); + + class Source { + + private final String firstName; + private final String lastName; + + public Source(String firstName, String lastName) { + this.firstName = firstName; + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public String getLastName() { + return lastName; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/SingleProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/SingleProperty.kt new file mode 100644 index 0000000000..1bb63c410d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/SingleProperty.kt @@ -0,0 +1,11 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class SingleProperty(val value: String?) diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/SinglePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/SinglePropertyMapper.java new file mode 100644 index 0000000000..d3d70f261c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/SinglePropertyMapper.java @@ -0,0 +1,32 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SinglePropertyMapper { + + SinglePropertyMapper INSTANCE = Mappers.getMapper( SinglePropertyMapper.class ); + + SingleProperty map(Source source); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/UnsignedProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/UnsignedProperty.kt new file mode 100644 index 0000000000..c52426b3af --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/UnsignedProperty.kt @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data + +/** + * @author Filip Hrisafov + */ +data class UnsignedProperty(val age: UInt?) { + // Java-friendly secondary constructor + constructor(age: Int?) : this(age?.toUInt()) + + @JvmName("getAge") + fun getAgeAsLong(): Long? = age?.toLong() +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/UnsignedPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/UnsignedPropertyMapper.java new file mode 100644 index 0000000000..4f055c7b41 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/UnsignedPropertyMapper.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface UnsignedPropertyMapper { + + UnsignedPropertyMapper INSTANCE = Mappers.getMapper( UnsignedPropertyMapper.class ); + + UnsignedProperty map(Source source); + + Source map(UnsignedProperty property); + + class Source { + + private final int age; + + public Source(int age) { + this.age = age; + } + + public int getAge() { + return age; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/KotlinDataJdk17Test.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/KotlinDataJdk17Test.java new file mode 100644 index 0000000000..bea5ca9bd4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/KotlinDataJdk17Test.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data.jdk17; + +import org.junit.jupiter.api.Nested; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithKotlin; +import org.mapstruct.ap.testutil.WithKotlinSources; +import org.mapstruct.ap.testutil.runner.Compiler; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +class KotlinDataJdk17Test { + + @Nested + @WithKotlinSources(value = "RecordProperty.kt") + @WithClasses(RecordPropertyMapper.class) + class Record { + + @ProcessorTest(Compiler.JDK) + @WithKotlin + void withKotlin() { + RecordPropertyMapper.Source source = new RecordPropertyMapper.Source(); + source.setFirstName( "John" ); + source.setLastName( "Doe" ); + + RecordProperty property = RecordPropertyMapper.INSTANCE.map( source ); + assertThat( property ).isNotNull(); + assertThat( property.firstName() ).isEqualTo( "John" ); + assertThat( property.lastName() ).isEqualTo( "Doe" ); + + source = RecordPropertyMapper.INSTANCE.map( property ); + assertThat( source ).isNotNull(); + assertThat( source.getFirstName() ).isEqualTo( "John" ); + assertThat( source.getLastName() ).isEqualTo( "Doe" ); + } + + @ProcessorTest(Compiler.JDK) + void withoutKotlin() { + RecordPropertyMapper.Source source = new RecordPropertyMapper.Source(); + source.setFirstName( "John" ); + source.setLastName( "Doe" ); + + RecordProperty property = RecordPropertyMapper.INSTANCE.map( source ); + assertThat( property ).isNotNull(); + assertThat( property.firstName() ).isEqualTo( "John" ); + assertThat( property.lastName() ).isEqualTo( "Doe" ); + + source = RecordPropertyMapper.INSTANCE.map( property ); + assertThat( source ).isNotNull(); + assertThat( source.getFirstName() ).isEqualTo( "John" ); + assertThat( source.getLastName() ).isEqualTo( "Doe" ); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/RecordProperty.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/RecordProperty.kt new file mode 100644 index 0000000000..28e8c9cfad --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/RecordProperty.kt @@ -0,0 +1,12 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data.jdk17 + +/** + * @author Filip Hrisafov + */ +@JvmRecord +data class RecordProperty(val firstName: String?, val lastName: String?) diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/RecordPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/RecordPropertyMapper.java new file mode 100644 index 0000000000..ecbc235aa5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/data/jdk17/RecordPropertyMapper.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.data.jdk17; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface RecordPropertyMapper { + + RecordPropertyMapper INSTANCE = Mappers.getMapper( RecordPropertyMapper.class ); + + RecordProperty map(Source source); + + Source map(RecordProperty source); + + class Source { + + private String firstName; + private String lastName; + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/Dtos.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/Dtos.kt new file mode 100644 index 0000000000..5a9084a685 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/Dtos.kt @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.sealed + +sealed class VehicleDto { + var name: String? = null + var maker: String? = null + + class BikeDto : VehicleDto() { + var numberOfGears: Int = 0 + } + + class CarDto : VehicleDto() { + var manual: Boolean = false + } + +} + +sealed class MotorDto : VehicleDto() { + var cc: Int = 0 + + class DavidsonDto : MotorDto() { + var numberOfExhausts: Int = 0 + } + + class HarleyDto : MotorDto() { + var engineDb: Int = 0 + } +} + +class VehicleCollectionDto { + var vehicles: MutableList = mutableListOf() +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/Entities.kt b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/Entities.kt new file mode 100644 index 0000000000..b380bac231 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/Entities.kt @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.sealed + +sealed class Vehicle { + var name: String? = null + var vehicleManufacturingCompany: String? = null + + class Bike : Vehicle() { + var numberOfGears: Int = 0 + } + + class Car : Vehicle() { + var manual: Boolean = false + } + +} + +sealed class Motor : Vehicle() { + var cc: Int = 0 + + class Davidson : Motor() { + var numberOfExhausts: Int = 0 + } + + class Harley : Motor() { + var engineDb: Int = 0 + } +} + +class VehicleCollection { + var vehicles: MutableList = mutableListOf() +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/SealedSubclassMapper.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/SealedSubclassMapper.java new file mode 100644 index 0000000000..bde7dc24cf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/SealedSubclassMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.sealed; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.SubclassMapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SealedSubclassMapper { + SealedSubclassMapper INSTANCE = Mappers.getMapper( SealedSubclassMapper.class ); + + VehicleCollectionDto map(VehicleCollection vehicles); + + @SubclassMapping( source = Vehicle.Car.class, target = VehicleDto.CarDto.class ) + @SubclassMapping( source = Vehicle.Bike.class, target = VehicleDto.BikeDto.class ) + @SubclassMapping( source = Motor.Harley.class, target = MotorDto.HarleyDto.class ) + @SubclassMapping( source = Motor.Davidson.class, target = MotorDto.DavidsonDto.class ) + @Mapping( source = "vehicleManufacturingCompany", target = "maker") + VehicleDto map(Vehicle vehicle); + + VehicleCollection mapInverse(VehicleCollectionDto vehicles); + + @InheritInverseConfiguration + Vehicle mapInverse(VehicleDto dto); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/SealedSubclassTest.java b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/SealedSubclassTest.java new file mode 100644 index 0000000000..f7162ec3a2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/kotlin/sealed/SealedSubclassTest.java @@ -0,0 +1,80 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.kotlin.sealed; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithKotlin; +import org.mapstruct.ap.testutil.WithKotlinSources; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + SealedSubclassMapper.class, +}) +@WithKotlinSources({ + "Dtos.kt", + "Entities.kt" +}) +@WithKotlin +public class SealedSubclassTest { + + @ProcessorTest + public void mappingIsDoneUsingSubclassMapping() { + VehicleCollection vehicles = new VehicleCollection(); + vehicles.getVehicles().add( new Vehicle.Car() ); + vehicles.getVehicles().add( new Vehicle.Bike() ); + vehicles.getVehicles().add( new Motor.Harley() ); + vehicles.getVehicles().add( new Motor.Davidson() ); + + VehicleCollectionDto result = SealedSubclassMapper.INSTANCE.map( vehicles ); + + assertThat( result.getVehicles() ).doesNotContainNull(); + assertThat( result.getVehicles() ) // remove generic so that test works. + .extracting( vehicle -> (Class) vehicle.getClass() ) + .containsExactly( + VehicleDto.CarDto.class, + VehicleDto.BikeDto.class, + MotorDto.HarleyDto.class, + MotorDto.DavidsonDto.class + ); + } + + @ProcessorTest + public void inverseMappingIsDoneUsingSubclassMapping() { + VehicleCollectionDto vehicles = new VehicleCollectionDto(); + vehicles.getVehicles().add( new VehicleDto.CarDto() ); + vehicles.getVehicles().add( new VehicleDto.BikeDto() ); + vehicles.getVehicles().add( new MotorDto.HarleyDto() ); + vehicles.getVehicles().add( new MotorDto.DavidsonDto() ); + + VehicleCollection result = SealedSubclassMapper.INSTANCE.mapInverse( vehicles ); + + assertThat( result.getVehicles() ).doesNotContainNull(); + assertThat( result.getVehicles() ) // remove generic so that test works. + .extracting( vehicle -> (Class) vehicle.getClass() ) + .containsExactly( + Vehicle.Car.class, + Vehicle.Bike.class, + Motor.Harley.class, + Motor.Davidson.class + ); + } + + @ProcessorTest + public void subclassMappingInheritsInverseMapping() { + VehicleCollectionDto vehiclesDto = new VehicleCollectionDto(); + VehicleDto.CarDto carDto = new VehicleDto.CarDto(); + carDto.setMaker( "BenZ" ); + vehiclesDto.getVehicles().add( carDto ); + + VehicleCollection result = SealedSubclassMapper.INSTANCE.mapInverse( vehiclesDto ); + + assertThat( result.getVehicles() ) + .extracting( Vehicle::getVehicleManufacturingCompany ) + .containsExactly( "BenZ" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarDto.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarDto.java index 02f74b0591..84354e3eab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarEntity.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarEntity.java index fda7dba5d3..b522563801 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/BarEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CentralConfig.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CentralConfig.java index a23e0ccac4..3caeb8cbba 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CentralConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CentralConfig.java @@ -1,23 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; +import org.mapstruct.ClassAccessibility; import org.mapstruct.MapperConfig; import org.mapstruct.ReportingPolicy; @@ -25,7 +13,9 @@ * * @author Sjaak Derksen */ -@MapperConfig(uses = { CustomMapperViaMapperConfig.class }, unmappedTargetPolicy = ReportingPolicy.ERROR ) +@MapperConfig(uses = {CustomMapperViaMapperConfig.class}, + unmappedTargetPolicy = ReportingPolicy.ERROR, + accessibility = ClassAccessibility.PACKAGE_PRIVATE) public class CentralConfig { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/ConfigTest.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/ConfigTest.java index 84decf0c90..a13db4ab0b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/ConfigTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/ConfigTest.java @@ -1,33 +1,21 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static java.lang.reflect.Modifier.isPrivate; +import static java.lang.reflect.Modifier.isProtected; +import static java.lang.reflect.Modifier.isPublic; +import static org.assertj.core.api.Assertions.assertThat; /** * @@ -44,10 +32,9 @@ CustomMapperViaMapperConfig.class, SourceTargetMapper.class } ) -@RunWith(AnnotationProcessorTestRunner.class) public class ConfigTest { - @Test + @ProcessorTest @WithClasses( { Target.class, SourceTargetMapper.class } ) public void shouldUseCustomMapperViaMapperForFooToEntity() { @@ -56,7 +43,7 @@ public void shouldUseCustomMapperViaMapperForFooToEntity() { assertThat( target.getFoo().getCreatedBy() ).isEqualTo( CustomMapperViaMapper.class.getSimpleName() ); } - @Test + @ProcessorTest @WithClasses( { Target.class, SourceTargetMapper.class } ) public void shouldUseCustomMapperViaMapperConfigForFooToDto() { @@ -65,25 +52,40 @@ public void shouldUseCustomMapperViaMapperConfigForFooToDto() { assertThat( source.getFoo().getCreatedBy() ).isEqualTo( CustomMapperViaMapperConfig.class.getSimpleName() ); } - @Test + @ProcessorTest + @WithClasses( { Target.class, SourceTargetMapper.class } ) + public void shouldDeclareMapperImplementationAsPackagePrivate() throws ClassNotFoundException { + Class implementation = loadForMapper( SourceTargetMapper.class ); + assertThat( isDefault( implementation.getModifiers() ) ).isTrue(); + } + + @ProcessorTest @WithClasses( { TargetNoFoo.class, SourceTargetMapperWarn.class } ) @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED, diagnostics = { @Diagnostic(type = SourceTargetMapperWarn.class, - kind = javax.tools.Diagnostic.Kind.WARNING, line = 37, - messageRegExp = "Unmapped target property: \"noFoo\"") + kind = javax.tools.Diagnostic.Kind.WARNING, line = 24, + message = "Unmapped target property: \"noFoo\".") }) public void shouldUseWARNViaMapper() { } - @Test + @ProcessorTest @WithClasses( { TargetNoFoo.class, SourceTargetMapperErroneous.class } ) @ExpectedCompilationOutcome(value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = SourceTargetMapperErroneous.class, - kind = javax.tools.Diagnostic.Kind.ERROR, line = 33, - messageRegExp = "Unmapped target property: \"noFoo\"") + kind = javax.tools.Diagnostic.Kind.ERROR, line = 20, + message = "Unmapped target property: \"noFoo\".") }) public void shouldUseERRORViaMapperConfig() { } + + private static Class loadForMapper(Class mapper) throws ClassNotFoundException { + return Thread.currentThread().getContextClassLoader().loadClass( mapper.getName() + "Impl" ); + } + + private static boolean isDefault(int modifiers) { + return !isPublic( modifiers ) && !isProtected( modifiers ) && !isPrivate( modifiers ); + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapper.java index baebee1cb6..756c06b787 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapperConfig.java index 69e31bb336..f8749e93c8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapperConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/CustomMapperViaMapperConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooDto.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooDto.java index 3313512e74..6d31877923 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooEntity.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooEntity.java index ca38b6d6b2..f8a454f7d1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/FooEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Source.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Source.java index b85d54b529..b20d04c9c9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapper.java index 681f8a5fe6..e392c6b14a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperErroneous.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperErroneous.java index f10fe115f6..881eea9b1c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperErroneous.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperErroneous.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperWarn.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperWarn.java index e2acefc1f8..0003b703ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperWarn.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/SourceTargetMapperWarn.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Target.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Target.java index ecea6ef40f..ba85076a98 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/TargetNoFoo.java b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/TargetNoFoo.java index c5d79becda..a75d735215 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/TargetNoFoo.java +++ b/processor/src/test/java/org/mapstruct/ap/test/mapperconfig/TargetNoFoo.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.mapperconfig; diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/BoxDto.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/BoxDto.java new file mode 100644 index 0000000000..1e984b792e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/BoxDto.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +public class BoxDto { + + private String groupName; + private String designation; + private ShelveDto shelve; + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getDesignation() { + return designation; + } + + public void setDesignation(String designation) { + this.designation = designation; + } + + public ShelveDto getShelve() { + return shelve; + } + + public void setShelve(ShelveDto shelve) { + this.shelve = shelve; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/BoxEntity.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/BoxEntity.java new file mode 100644 index 0000000000..d0baa7c9d5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/BoxEntity.java @@ -0,0 +1,57 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +import java.util.Date; + +public class BoxEntity { + + private Date creationDate; + private Long id; + private String name; + private String label; + private ShelveEntity shelve; + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public ShelveEntity getShelve() { + return shelve; + } + + public void setShelve(ShelveEntity shelve) { + this.shelve = shelve; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/CompositionTest.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/CompositionTest.java new file mode 100644 index 0000000000..0a5a361313 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/CompositionTest.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +import java.util.Date; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * + * @author Sjaak Derksen + */ +@IssueKey("807") +@WithClasses({ + BoxDto.class, + BoxEntity.class, + ShelveDto.class, + ShelveEntity.class, + StorageMapper.class, + ToEntity.class +}) +public class CompositionTest { + + @ProcessorTest + public void shouldCompose() { + + Date now = new Date(); + Date anHourAgo = new Date( now.getTime() - 3600 * 1000 ); + Date anHourFromNow = new Date( now.getTime() + 3600 * 1000 ); + + ShelveDto shelve = new ShelveDto(); + shelve.setGroupName( "blue things" ); + shelve.setMaxWeight( 10.0d ); + shelve.setPath( "row5" ); + shelve.setStandNumber( 3 ); + + BoxDto box = new BoxDto(); + box.setDesignation( "blue item" ); + box.setGroupName( "blue stuff" ); + box.setShelve( shelve ); + + BoxEntity boxEntity = StorageMapper.INSTANCE.map( box ); + + // box + assertThat( boxEntity ).isNotNull(); + assertThat( boxEntity.getCreationDate() ).isBetween( anHourAgo, anHourFromNow ); + assertThat( boxEntity.getId() ).isNull(); + assertThat( boxEntity.getName() ).isEqualTo( "blue stuff" ); + assertThat( boxEntity.getLabel() ).isEqualTo( "blue item" ); + + // shelve + ShelveEntity shelveEntity = boxEntity.getShelve(); + assertThat( shelveEntity.getCreationDate() ).isBetween( anHourAgo, anHourFromNow ); + assertThat( shelveEntity.getId() ).isNull(); + assertThat( shelveEntity.getName() ).isEqualTo( "blue things" ); + assertThat( shelveEntity.getPath() ).isEqualTo( "row5" ); + assertThat( shelveEntity.getStandNumber() ).isEqualTo( 3 ); + assertThat( shelveEntity.getWeightLimit() ).isEqualTo( 10.0d ); + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ShelveDto.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ShelveDto.java new file mode 100644 index 0000000000..37cfe79036 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ShelveDto.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +public class ShelveDto { + + private String groupName; + private String path; + private int standNumber; + private double maxWeight; + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getStandNumber() { + return standNumber; + } + + public void setStandNumber(int standNumber) { + this.standNumber = standNumber; + } + + public double getMaxWeight() { + return maxWeight; + } + + public void setMaxWeight(double maxWeight) { + this.maxWeight = maxWeight; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ShelveEntity.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ShelveEntity.java new file mode 100644 index 0000000000..39a397c7cb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ShelveEntity.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +import java.util.Date; + +public class ShelveEntity { + + private Date creationDate; + private Long id; + private String name; + + private String path; + private int standNumber; + private double weightLimit; + + public Date getCreationDate() { + return creationDate; + } + + public void setCreationDate(Date creationDate) { + this.creationDate = creationDate; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public int getStandNumber() { + return standNumber; + } + + public void setStandNumber(int standNumber) { + this.standNumber = standNumber; + } + + public double getWeightLimit() { + return weightLimit; + } + + public void setWeightLimit(double weightLimit) { + this.weightLimit = weightLimit; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/StorageMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/StorageMapper.java new file mode 100644 index 0000000000..5136968019 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/StorageMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface StorageMapper { + + StorageMapper INSTANCE = Mappers.getMapper( StorageMapper.class ); + + @ToEntity + @Mapping( target = "weightLimit", source = "maxWeight") + ShelveEntity map(ShelveDto source); + + @ToEntity + @Mapping( target = "label", source = "designation") + BoxEntity map(BoxDto source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ToEntity.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ToEntity.java new file mode 100644 index 0000000000..4cbd94c665 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcomposition/ToEntity.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcomposition; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.mapstruct.Mapping; + +@Retention(RetentionPolicy.CLASS) +@Mapping(target = "id", ignore = true) +@Mapping(target = "creationDate", expression = "java(new java.util.Date())") +@Mapping(target = "name", source = "groupName") +public @interface ToEntity { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningBeanMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningBeanMappingMapper.java new file mode 100644 index 0000000000..a5c05d974d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningBeanMappingMapper.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CloningBeanMappingMapper { + + CloningBeanMappingMapper INSTANCE = Mappers.getMapper( CloningBeanMappingMapper.class ); + + @BeanMapping(mappingControl = DeepClone.class) + FridgeDTO clone(FridgeDTO in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningListMapper.java new file mode 100644 index 0000000000..5a74527d36 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningListMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = DeepClone.class) +public interface CloningListMapper { + + CloningListMapper INSTANCE = Mappers.getMapper( CloningListMapper.class ); + + CustomerDto clone(CustomerDto in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningMapper.java new file mode 100644 index 0000000000..c1ff968d2c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CloningMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.control.DeepClone; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = DeepClone.class) +public interface CloningMapper { + + CloningMapper INSTANCE = Mappers.getMapper( CloningMapper.class ); + + FridgeDTO clone(FridgeDTO in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ComplexMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ComplexMapper.java new file mode 100644 index 0000000000..768e6117a5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ComplexMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ComplexMapper { + + ComplexMapper INSTANCE = Mappers.getMapper( ComplexMapper.class ); + + @Mapping(target = "beerCount", source = "shelve") + Fridge map(FridgeDTO in); + + default String toBeerCount(ShelveDTO in) { + return in.getCoolBeer().getBeerCount(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/Config.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/Config.java new file mode 100644 index 0000000000..b37c8e4f25 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/Config.java @@ -0,0 +1,16 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.MapperConfig; +import org.mapstruct.control.NoComplexMapping; + +/** + * @author Sjaak Derksen + */ +@MapperConfig( mappingControl = NoComplexMapping.class ) +public interface Config { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ConversionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ConversionMapper.java new file mode 100644 index 0000000000..d4e1c3249d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ConversionMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface ConversionMapper { + + ConversionMapper INSTANCE = Mappers.getMapper( ConversionMapper.class ); + + Fridge map(CoolBeerDTO in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CoolBeerDTO.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CoolBeerDTO.java new file mode 100644 index 0000000000..1505d3f291 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CoolBeerDTO.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +public class CoolBeerDTO { + + private String beerCount; + + public String getBeerCount() { + return beerCount; + } + + public void setBeerCount(String beerCount) { + this.beerCount = beerCount; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CustomerDto.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CustomerDto.java new file mode 100644 index 0000000000..810d53f41e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/CustomerDto.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.util.List; +import java.util.Map; + +/** + * @author Sjaak Derksen + */ +public class CustomerDto { + + private Long id; + private String customerName; + private List orders; + private Map stock; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getCustomerName() { + return customerName; + } + + public void setCustomerName(String customerName) { + this.customerName = customerName; + } + + public List getOrders() { + return orders; + } + + public void setOrders(List orders) { + this.orders = orders; + } + + public Map getStock() { + return stock; + } + + public void setStock(Map stock) { + this.stock = stock; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/DirectMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/DirectMapper.java new file mode 100644 index 0000000000..1529c15eb1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/DirectMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface DirectMapper { + + DirectMapper INSTANCE = Mappers.getMapper( DirectMapper.class ); + + @Mapping(target = "shelve", source = "shelve") + FridgeDTO map(FridgeDTO in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousBuiltInAndBuiltInMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousBuiltInAndBuiltInMapper.java new file mode 100644 index 0000000000..eb9f7ea9ce --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousBuiltInAndBuiltInMapper.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.time.ZonedDateTime; +import java.util.Date; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(mappingControl = NoConversion.class) +public interface ErroneousBuiltInAndBuiltInMapper { + + Target map(Source source); + + class Source { + private final ZonedDateTime time; + + public Source(ZonedDateTime time) { + this.time = time; + } + + public ZonedDateTime getTime() { + return time; + } + } + + class Target { + private final Date time; + + public Target(Date time) { + this.time = time; + } + + public Date getTime() { + return time; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousBuiltInAndMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousBuiltInAndMethodMapper.java new file mode 100644 index 0000000000..fdd7545da7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousBuiltInAndMethodMapper.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.util.Calendar; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(mappingControl = NoConversion.class) +public interface ErroneousBuiltInAndMethodMapper { + + Target map(Source source); + + default ZonedDateTime fromInt(int time) { + return ZonedDateTime.ofInstant( Instant.ofEpochMilli( time ), ZoneOffset.UTC ); + } + + class Source { + private final int time; + + public Source(int time) { + this.time = time; + } + + public int getTime() { + return time; + } + } + + class Target { + private Calendar time; + + public Target(Calendar time) { + this.time = time; + } + + public Calendar getTime() { + return time; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousComplexMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousComplexMapper.java new file mode 100644 index 0000000000..71eaf227ae --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousComplexMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = UseDirect.class) +public interface ErroneousComplexMapper { + + ErroneousComplexMapper INSTANCE = Mappers.getMapper( ErroneousComplexMapper.class ); + + @Mapping(target = "beerCount", source = "shelve") + Fridge map(FridgeDTO in); + + default String toBeerCount(ShelveDTO in) { + return in.getCoolBeer().getBeerCount(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousComplexMapperWithConfig.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousComplexMapperWithConfig.java new file mode 100644 index 0000000000..ecb9c58837 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousComplexMapperWithConfig.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper(config = Config.class) +public interface ErroneousComplexMapperWithConfig { + + ErroneousComplexMapperWithConfig INSTANCE = Mappers.getMapper( ErroneousComplexMapperWithConfig.class ); + + @Mapping(target = "beerCount", source = "shelve") + Fridge map(FridgeDTO in); + + default String toBeerCount(ShelveDTO in) { + return in.getCoolBeer().getBeerCount(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousConversionAndMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousConversionAndMethodMapper.java new file mode 100644 index 0000000000..91a94aeca2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousConversionAndMethodMapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.time.Instant; +import java.util.Date; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(mappingControl = NoConversion.class) +public interface ErroneousConversionAndMethodMapper { + + Target map(Source source); + + default Instant fromDate(int time) { + return Instant.ofEpochMilli( time ); + } + + class Source { + private final int time; + + public Source(int time) { + this.time = time; + } + + public int getTime() { + return time; + } + } + + class Target { + private Date time; + + public Target(Date time) { + this.time = time; + } + + public Date getTime() { + return time; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousConversionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousConversionMapper.java new file mode 100644 index 0000000000..a7f09e40e2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousConversionMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = UseDirect.class) +public interface ErroneousConversionMapper { + + ErroneousConversionMapper INSTANCE = Mappers.getMapper( ErroneousConversionMapper.class ); + + Fridge map(CoolBeerDTO in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousDirectMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousDirectMapper.java new file mode 100644 index 0000000000..672c9bd7c8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousDirectMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = UseComplex.class) +public interface ErroneousDirectMapper { + + ErroneousDirectMapper INSTANCE = Mappers.getMapper( ErroneousDirectMapper.class ); + + @Mapping(target = "shelve", source = "shelve") + FridgeDTO map(FridgeDTO in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodAndBuiltInMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodAndBuiltInMapper.java new file mode 100644 index 0000000000..d7798161c1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodAndBuiltInMapper.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.time.ZonedDateTime; +import java.util.Calendar; +import java.util.Date; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(mappingControl = NoConversion.class) +public interface ErroneousMethodAndBuiltInMapper { + + Target map(Source source); + + default Date fromCalendar(Calendar calendar) { + return calendar != null ? calendar.getTime() : null; + } + + class Source { + private final ZonedDateTime time; + + public Source(ZonedDateTime time) { + this.time = time; + } + + public ZonedDateTime getTime() { + return time; + } + } + + class Target { + private final Date time; + + public Target(Date time) { + this.time = time; + } + + public Date getTime() { + return time; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodAndConversionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodAndConversionMapper.java new file mode 100644 index 0000000000..5a372addd9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodAndConversionMapper.java @@ -0,0 +1,48 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.time.Instant; +import java.util.Date; + +import org.mapstruct.Mapper; + +/** + * @author Filip Hrisafov + */ +@Mapper(mappingControl = NoConversion.class) +public interface ErroneousMethodAndConversionMapper { + + Target map(Source source); + + default long fromInstant(Instant value) { + return value != null ? value.getEpochSecond() : null; + } + + class Source { + private final Date time; + + public Source(Date time) { + this.time = time; + } + + public Date getTime() { + return time; + } + } + + class Target { + private long time; + + public Target(long time) { + this.time = time; + } + + public long getTime() { + return time; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodMapper.java new file mode 100644 index 0000000000..276c37a6e7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ErroneousMethodMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper(mappingControl = UseDirect.class) +public interface ErroneousMethodMapper { + + ErroneousMethodMapper INSTANCE = Mappers.getMapper( ErroneousMethodMapper.class ); + + @Mapping(target = "beerCount", source = "shelve") + Fridge map(FridgeDTO in); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/Fridge.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/Fridge.java new file mode 100644 index 0000000000..52d0f0e376 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/Fridge.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +public class Fridge { + + private int beerCount; + + public int getBeerCount() { + return beerCount; + } + + public void setBeerCount(int beerCount) { + this.beerCount = beerCount; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/FridgeDTO.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/FridgeDTO.java new file mode 100644 index 0000000000..0951278619 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/FridgeDTO.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +public class FridgeDTO { + + private ShelveDTO shelve; + + public ShelveDTO getShelve() { + return shelve; + } + + public void setShelve(ShelveDTO shelve) { + this.shelve = shelve; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/MappingControlTest.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/MappingControlTest.java new file mode 100644 index 0000000000..171fe4bc6a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/MappingControlTest.java @@ -0,0 +1,342 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +/** + * @author Sjaak Derksen + */ +@IssueKey("695") +@WithClasses({ + CoolBeerDTO.class, + ShelveDTO.class, + Fridge.class, + FridgeDTO.class, + CustomerDto.class, + OrderItemDto.class, + OrderItemKeyDto.class, + UseDirect.class, + UseComplex.class +}) +public class MappingControlTest { + + /** + * Baseline Test, normal, direct allowed + */ + @ProcessorTest + @WithClasses(DirectMapper.class) + public void directSelectionAllowed() { + + FridgeDTO in = createFridgeDTO(); + FridgeDTO out = DirectMapper.INSTANCE.map( in ); + + assertThat( out ).isNotNull(); + assertThat( out.getShelve() ).isNotNull(); + assertThat( out.getShelve() ).isSameAs( in.getShelve() ); + } + + /** + * Test the deep cloning annotation + */ + @ProcessorTest + @WithClasses(CloningMapper.class) + public void testDeepCloning() { + + FridgeDTO in = createFridgeDTO(); + FridgeDTO out = CloningMapper.INSTANCE.clone( in ); + + assertThat( out ).isNotNull(); + assertThat( out.getShelve() ).isNotNull(); + assertThat( out.getShelve() ).isNotSameAs( in.getShelve() ); + assertThat( out.getShelve().getCoolBeer() ).isNotSameAs( in.getShelve().getCoolBeer() ); + assertThat( out.getShelve().getCoolBeer().getBeerCount() ).isEqualTo( "5" ); + } + + @ProcessorTest + @IssueKey("3135") + @WithClasses(CloningBeanMappingMapper.class) + public void testDeepCloningViaBeanMapping() { + + FridgeDTO in = createFridgeDTO(); + FridgeDTO out = CloningBeanMappingMapper.INSTANCE.clone( in ); + + assertThat( out ).isNotNull(); + assertThat( out.getShelve() ).isNotNull(); + assertThat( out.getShelve() ).isNotSameAs( in.getShelve() ); + assertThat( out.getShelve().getCoolBeer() ).isNotSameAs( in.getShelve().getCoolBeer() ); + assertThat( out.getShelve().getCoolBeer().getBeerCount() ).isEqualTo( "5" ); + } + + /** + * Test the deep cloning annotation with lists + */ + @ProcessorTest + @WithClasses(CloningListMapper.class) + public void testDeepCloningListsAndMaps() { + + CustomerDto in = new CustomerDto(); + in.setId( 10L ); + in.setCustomerName( "Jaques" ); + OrderItemDto order1 = new OrderItemDto(); + order1.setName( "Table" ); + order1.setQuantity( 2L ); + in.setOrders( new ArrayList<>( Collections.singleton( order1 ) ) ); + OrderItemKeyDto key = new OrderItemKeyDto(); + key.setStockNumber( 5 ); + Map stock = new HashMap<>(); + stock.put( key, order1 ); + in.setStock( stock ); + + CustomerDto out = CloningListMapper.INSTANCE.clone( in ); + + assertThat( out.getId() ).isEqualTo( 10 ); + assertThat( out.getCustomerName() ).isEqualTo( "Jaques" ); + assertThat( out.getOrders() ) + .extracting( "name", "quantity" ) + .containsExactly( tuple( "Table", 2L ) ); + assertThat( out.getStock() ).isNotNull(); + assertThat( out.getStock() ).hasSize( 1 ); + + Map.Entry entry = out.getStock().entrySet().iterator().next(); + assertThat( entry.getKey().getStockNumber() ).isEqualTo( 5 ); + assertThat( entry.getValue().getName() ).isEqualTo( "Table" ); + assertThat( entry.getValue().getQuantity() ).isEqualTo( 2L ); + + // check mapper really created new objects + assertThat( out ).isNotSameAs( in ); + assertThat( out.getOrders().get( 0 ) ).isNotSameAs( order1 ); + assertThat( entry.getKey() ).isNotSameAs( key ); + assertThat( entry.getValue() ).isNotSameAs( order1 ); + assertThat( entry.getValue() ).isNotSameAs( out.getOrders().get( 0 ) ); + } + + /** + * This is a nice test. MapStruct looks for a way to map ShelveDto to ShelveDto. + *

        + * MapStruct gets too creative when we allow complex (2 step mappings) to convert if we also allow + * it to forge methods (which is contradiction with the fact that we do not allow methods on this mapper) + */ + @ProcessorTest + @WithClasses(ErroneousDirectMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousDirectMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Can't map property \"ShelveDTO shelve\" to \"ShelveDTO shelve\". " + + "Consider to declare/implement a mapping method: \"ShelveDTO map(ShelveDTO value)\"." + ) + }) + public void directSelectionNotAllowed() { + } + + /** + * Baseline Test, normal, method allowed + */ + @ProcessorTest + @WithClasses(MethodMapper.class) + public void methodSelectionAllowed() { + Fridge fridge = MethodMapper.INSTANCE.map( createFridgeDTO() ); + + assertThat( fridge ).isNotNull(); + assertThat( fridge.getBeerCount() ).isEqualTo( 5 ); + assertThat( fridge.getBeerCount() ).isEqualTo( 5 ); + } + + @ProcessorTest + @WithClasses(ErroneousMethodMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMethodMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Can't map property \"ShelveDTO shelve\" to \"int beerCount\". " + + "Consider to declare/implement a mapping method: \"int map(ShelveDTO value)\"." + ) + }) + public void methodSelectionNotAllowed() { + } + + /** + * Baseline Test, normal, conversion allowed + */ + @ProcessorTest + @WithClasses(ConversionMapper.class) + public void conversionSelectionAllowed() { + Fridge fridge = ConversionMapper.INSTANCE.map( createFridgeDTO().getShelve().getCoolBeer() ); + + assertThat( fridge ).isNotNull(); + assertThat( fridge.getBeerCount() ).isEqualTo( 5 ); + } + + @ProcessorTest + @WithClasses(ErroneousConversionMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousConversionMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Can't map property \"String beerCount\" to \"int beerCount\". " + + "Consider to declare/implement a mapping method: \"int map(String value)\"." + ) + }) + public void conversionSelectionNotAllowed() { + } + + /** + * Baseline Test, normal, complex mapping allowed + */ + @ProcessorTest + @WithClasses(ComplexMapper.class) + public void complexSelectionAllowed() { + Fridge fridge = ComplexMapper.INSTANCE.map( createFridgeDTO() ); + + assertThat( fridge ).isNotNull(); + assertThat( fridge.getBeerCount() ).isEqualTo( 5 ); + } + + @ProcessorTest + @WithClasses(ErroneousComplexMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousComplexMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Can't map property \"ShelveDTO shelve\" to \"int beerCount\". " + + "Consider to declare/implement a mapping method: \"int map(ShelveDTO value)\"." + ) + }) + public void complexSelectionNotAllowed() { + } + + @ProcessorTest + @WithClasses({ Config.class, ErroneousComplexMapperWithConfig.class }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousComplexMapperWithConfig.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 17, + message = "Can't map property \"ShelveDTO shelve\" to \"int beerCount\". " + + "Consider to declare/implement a mapping method: \"int map(ShelveDTO value)\"." + ) + }) + public void complexSelectionNotAllowedWithConfig() { + } + + @ProcessorTest + @IssueKey("3186") + @WithClasses({ + ErroneousMethodAndBuiltInMapper.class, + NoConversion.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMethodAndBuiltInMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + message = "Can't map property \"ZonedDateTime time\" to \"Date time\". " + + "Consider to declare/implement a mapping method: \"Date map(ZonedDateTime value)\"." + ) + }) + public void conversionSelectionNotAllowedInTwoStepMethodBuiltIdConversion() { + } + + @ProcessorTest + @IssueKey("3186") + @WithClasses({ + ErroneousBuiltInAndBuiltInMapper.class, + NoConversion.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousBuiltInAndBuiltInMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 19, + message = "Can't map property \"ZonedDateTime time\" to \"Date time\". " + + "Consider to declare/implement a mapping method: \"Date map(ZonedDateTime value)\"." + ) + }) + public void conversionSelectionNotAllowedInTwoStepBuiltInBuiltInConversion() { + } + + @ProcessorTest + @IssueKey("3186") + @WithClasses({ + ErroneousBuiltInAndMethodMapper.class, + NoConversion.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousBuiltInAndMethodMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 21, + message = "Can't map property \"int time\" to \"Calendar time\". " + + "Consider to declare/implement a mapping method: \"Calendar map(int value)\"." + ) + }) + public void conversionSelectionNotAllowedInTwoStepBuiltInMethodConversion() { + } + + @ProcessorTest + @IssueKey("3186") + @WithClasses({ + ErroneousMethodAndConversionMapper.class, + NoConversion.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousMethodAndConversionMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 19, + message = "Can't map property \"Date time\" to \"long time\". " + + "Consider to declare/implement a mapping method: \"long map(Date value)\"." + ) + }) + public void conversionSelectionNotAllowedInTwoStepMethodConversionConversion() { + } + + @ProcessorTest + @IssueKey("3186") + @WithClasses({ + ErroneousConversionAndMethodMapper.class, + NoConversion.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousConversionAndMethodMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 19, + message = "Can't map property \"int time\" to \"Date time\". " + + "Consider to declare/implement a mapping method: \"Date map(int value)\"." + ) + }) + public void conversionSelectionNotAllowedInTwoStepConversionMethodConversion() { + } + + private FridgeDTO createFridgeDTO() { + FridgeDTO fridgeDTO = new FridgeDTO(); + ShelveDTO shelveDTO = new ShelveDTO(); + CoolBeerDTO coolBeerDTO = new CoolBeerDTO(); + fridgeDTO.setShelve( shelveDTO ); + shelveDTO.setCoolBeer( coolBeerDTO ); + coolBeerDTO.setBeerCount( "5" ); + return fridgeDTO; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/MethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/MethodMapper.java new file mode 100644 index 0000000000..54e4515c52 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/MethodMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface MethodMapper { + + MethodMapper INSTANCE = Mappers.getMapper( MethodMapper.class ); + + @Mapping(target = "beerCount", source = "shelve") + Fridge map(FridgeDTO in); + + default int map(ShelveDTO in) { + return Integer.valueOf( in.getCoolBeer().getBeerCount() ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/NoConversion.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/NoConversion.java new file mode 100644 index 0000000000..6f05c16bb8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/NoConversion.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.mapstruct.control.MappingControl; +import org.mapstruct.util.Experimental; + +@Retention(RetentionPolicy.CLASS) +@Experimental +@MappingControl( MappingControl.Use.DIRECT ) +@MappingControl( MappingControl.Use.MAPPING_METHOD ) +@MappingControl( MappingControl.Use.COMPLEX_MAPPING ) +public @interface NoConversion { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/OrderItemDto.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/OrderItemDto.java new file mode 100644 index 0000000000..dbaad654d9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/OrderItemDto.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +/** + * @author Sjaak Derksen + */ +public class OrderItemDto { + + private String name; + private Long quantity; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getQuantity() { + return quantity; + } + + public void setQuantity(Long quantity) { + this.quantity = quantity; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/OrderItemKeyDto.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/OrderItemKeyDto.java new file mode 100644 index 0000000000..6154f4450b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/OrderItemKeyDto.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +/** + * @author Sjaak Derksen + */ +public class OrderItemKeyDto { + + private long stockNumber; + + public long getStockNumber() { + return stockNumber; + } + + public void setStockNumber(long stockNumber) { + this.stockNumber = stockNumber; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ShelveDTO.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ShelveDTO.java new file mode 100644 index 0000000000..0ddfeb7a2a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/ShelveDTO.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +public class ShelveDTO { + + private CoolBeerDTO coolBeer; + + public CoolBeerDTO getCoolBeer() { + return coolBeer; + } + + public void setCoolBeer(CoolBeerDTO coolBeer) { + this.coolBeer = coolBeer; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/UseComplex.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/UseComplex.java new file mode 100644 index 0000000000..2424d95300 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/UseComplex.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.mapstruct.control.MappingControl; +import org.mapstruct.util.Experimental; + +@Retention(RetentionPolicy.CLASS) +@Experimental +@MappingControl( MappingControl.Use.COMPLEX_MAPPING ) +public @interface UseComplex { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/UseDirect.java b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/UseDirect.java new file mode 100644 index 0000000000..00151d71ed --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/mappingcontrol/UseDirect.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.mappingcontrol; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +import org.mapstruct.control.MappingControl; +import org.mapstruct.util.Experimental; + +@Retention(RetentionPolicy.CLASS) +@Experimental +@MappingControl( MappingControl.Use.DIRECT ) +public @interface UseDirect { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/missingignoredsource/ErroneousSourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/missingignoredsource/ErroneousSourceTargetMapper.java new file mode 100644 index 0000000000..1196d773cb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/missingignoredsource/ErroneousSourceTargetMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.missingignoredsource; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +@Mapper( + unmappedTargetPolicy = ReportingPolicy.IGNORE, + unmappedSourcePolicy = ReportingPolicy.IGNORE) +public interface ErroneousSourceTargetMapper { + + @BeanMapping(ignoreUnmappedSourceProperties = "bar") + Target map(Target source); + + class Target { + private final String value; + + public Target(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/missingignoredsource/MissingIgnoredSourceTest.java b/processor/src/test/java/org/mapstruct/ap/test/missingignoredsource/MissingIgnoredSourceTest.java new file mode 100644 index 0000000000..5794126604 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/missingignoredsource/MissingIgnoredSourceTest.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.missingignoredsource; + +import javax.tools.Diagnostic.Kind; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +public class MissingIgnoredSourceTest { + + @ProcessorTest + @WithClasses({ ErroneousSourceTargetMapper.class }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousSourceTargetMapper.class, + kind = Kind.ERROR, + line = 18, + message = "Ignored unknown source property: \"bar\".") + } + ) + public void shouldRaiseErrorDueToMissingIgnoredSourceProperty() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/multisource/MultiSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/multisource/MultiSourceMapper.java new file mode 100644 index 0000000000..51ee997615 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/multisource/MultiSourceMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.multisource; + +import java.util.Collection; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface MultiSourceMapper { + + MultiSourceMapper INSTANCE = Mappers.getMapper( MultiSourceMapper.class ); + + Target mapFromPrimitiveAndCollection(int value, Collection elements); + + Target mapFromCollectionAndPrimitive(Collection elements, int value); + + class Target { + private int value; + private Collection elements; + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } + + public Collection getElements() { + return elements; + } + + public void setElements(Collection elements) { + this.elements = elements; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/multisource/MultiSourceMapperTest.java b/processor/src/test/java/org/mapstruct/ap/test/multisource/MultiSourceMapperTest.java new file mode 100644 index 0000000000..c4e1eaaee4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/multisource/MultiSourceMapperTest.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.multisource; + +import java.util.Collections; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +public class MultiSourceMapperTest { + + @IssueKey("2005") + @ProcessorTest + @WithClasses({ + MultiSourceMapper.class + }) + void shouldBeAbleToMapFromPrimitiveAndCollectionAsMultiSource() { + MultiSourceMapper.Target target = MultiSourceMapper.INSTANCE.mapFromPrimitiveAndCollection( + 10, + Collections.singleton( "test" ) + ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( 10 ); + assertThat( target.getElements() ).containsExactly( "test" ); + + target = MultiSourceMapper.INSTANCE.mapFromCollectionAndPrimitive( + Collections.singleton( "otherTest" ), + 20 + ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( 20 ); + assertThat( target.getElements() ).containsExactly( "otherTest" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgb.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgb.java index 9fa53911ed..03cdb1aa0f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgb.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgb.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgbDto.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgbDto.java index 55d5b05c63..c5070a3563 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgbDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/ColorRgbDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Garage.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Garage.java index 67c713be16..6ea1be3b06 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Garage.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Garage.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/GarageDto.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/GarageDto.java index 37543eb12a..d94c3ef7b1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/GarageDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/GarageDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Person.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Person.java index e80adb708f..6341e0002b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Person.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/Person.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/PersonDto.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/PersonDto.java index 13a804a9f1..a6febf074c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/PersonDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/PersonDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/SuggestMostSimilarNameTest.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/SuggestMostSimilarNameTest.java index 0b81d07020..079b2f3020 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/SuggestMostSimilarNameTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/SuggestMostSimilarNameTest.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.namesuggestion.erroneous.PersonAgeMapper; import org.mapstruct.ap.test.namesuggestion.erroneous.PersonGarageWrongSourceMapper; import org.mapstruct.ap.test.namesuggestion.erroneous.PersonGarageWrongTargetMapper; import org.mapstruct.ap.test.namesuggestion.erroneous.PersonNameMapper; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ Person.class, PersonDto.class, Garage.class, GarageDto.class, ColorRgb.class, ColorRgbDto.class }) public class SuggestMostSimilarNameTest { - @Test + @ProcessorTest @WithClasses({ PersonAgeMapper.class }) @@ -45,14 +29,14 @@ public class SuggestMostSimilarNameTest { diagnostics = { @Diagnostic(type = PersonAgeMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = ".*Did you mean \"age\"\\?") + line = 19, + message = "No property named \"agee\" exists in source parameter(s). Did you mean \"age\"?") } ) public void testAgeSuggestion() { } - @Test + @ProcessorTest @WithClasses({ PersonNameMapper.class }) @@ -61,14 +45,14 @@ public void testAgeSuggestion() { diagnostics = { @Diagnostic(type = PersonNameMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = ".*Did you mean \"fullName\"\\?") + line = 19, + message = "Unknown property \"fulName\" in result type Person. Did you mean \"fullName\"?") } ) public void testNameSuggestion() { } - @Test + @ProcessorTest @WithClasses({ PersonGarageWrongTargetMapper.class }) @@ -77,18 +61,28 @@ public void testNameSuggestion() { diagnostics = { @Diagnostic(type = PersonGarageWrongTargetMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = "Unknown property \"garage\\.colour\\.rgb\".*Did you mean \"garage\\.color\"\\?"), + line = 19, + message = "Unknown property \"colour\" in type Garage for target name \"garage.colour.rgb\". " + + "Did you mean \"garage.color\"?"), + @Diagnostic(type = PersonGarageWrongTargetMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 20, + messageRegExp = "Unmapped target properties: \"fullName, fullAge\"\\."), @Diagnostic(type = PersonGarageWrongTargetMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = "Unknown property \"garage\\.colour\".*Did you mean \"garage\\.color\"\\?") + line = 22, + message = "Unknown property \"colour\" in type Garage for target name \"garage.colour\". " + + "Did you mean \"garage.color\"?"), + @Diagnostic(type = PersonGarageWrongTargetMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 23, + messageRegExp = "Unmapped target properties: \"fullName, fullAge\"\\."), } ) public void testGarageTargetSuggestion() { } - @Test + @ProcessorTest @WithClasses({ PersonGarageWrongSourceMapper.class }) @@ -97,12 +91,14 @@ public void testGarageTargetSuggestion() { diagnostics = { @Diagnostic(type = PersonGarageWrongSourceMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 32, - messageRegExp = "No property named \"garage\\.colour\\.rgb\".*Did you mean \"garage\\.color\"\\?"), + line = 21, + message = "No property named \"garage.colour.rgb\" exists in source parameter(s). Did you mean " + + "\"garage.color\"?"), @Diagnostic(type = PersonGarageWrongSourceMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 35, - messageRegExp = "No property named \"garage\\.colour\".*Did you mean \"garage\\.color\"\\?") + line = 28, + message = "No property named \"garage.colour\" exists in source parameter(s). Did you mean \"garage" + + ".color\"?") } ) public void testGarageSourceSuggestion() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonAgeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonAgeMapper.java index e40058c6f0..9cf3de5e74 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonAgeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonAgeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion.erroneous; @@ -29,7 +16,7 @@ public interface PersonAgeMapper { PersonAgeMapper MAPPER = Mappers.getMapper( PersonAgeMapper.class ); - @Mapping(source = "agee", target = "fullAge") + @Mapping(target = "fullAge", source = "agee") Person mapPerson(PersonDto dto); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongSourceMapper.java index 40c5dc8f56..0fd3a06b0d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongSourceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongSourceMapper.java @@ -1,25 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion.erroneous; import org.mapstruct.Mapper; import org.mapstruct.Mapping; +import org.mapstruct.Mappings; import org.mapstruct.ap.test.namesuggestion.Person; import org.mapstruct.ap.test.namesuggestion.PersonDto; import org.mapstruct.factory.Mappers; @@ -29,10 +17,18 @@ public interface PersonGarageWrongSourceMapper { PersonGarageWrongSourceMapper MAPPER = Mappers.getMapper( PersonGarageWrongSourceMapper.class ); - @Mapping(source = "garage.colour.rgb", target = "garage.color.rgb") + @Mappings( { + @Mapping( target = "garage.color.rgb", source = "garage.colour.rgb" ), + @Mapping( target = "fullAge", source = "age" ), + @Mapping( target = "fullName", source = "name" ) + } ) Person mapPerson(PersonDto dto); - @Mapping(source = "garage.colour", target = "garage.color") + @Mappings( { + @Mapping( target = "garage.color", source = "garage.colour" ), + @Mapping( target = "fullAge", source = "age" ), + @Mapping( target = "fullName", source = "name" ) + } ) Person mapPersonGarage(PersonDto dto); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongTargetMapper.java index d462f54c16..fc587e0b71 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonGarageWrongTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion.erroneous; @@ -29,9 +16,9 @@ public interface PersonGarageWrongTargetMapper { PersonGarageWrongTargetMapper MAPPER = Mappers.getMapper( PersonGarageWrongTargetMapper.class ); - @Mapping(source = "garage.color.rgb", target = "garage.colour.rgb") + @Mapping(target = "garage.colour.rgb", source = "garage.color.rgb") Person mapPerson(PersonDto dto); - @Mapping(source = "garage.color", target = "garage.colour") + @Mapping(target = "garage.colour", source = "garage.color") Person mapPersonGarage(PersonDto dto); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonNameMapper.java b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonNameMapper.java index a6dab48610..b14a0d0cf9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonNameMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/namesuggestion/erroneous/PersonNameMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.namesuggestion.erroneous; @@ -29,7 +16,7 @@ public interface PersonNameMapper { PersonNameMapper MAPPER = Mappers.getMapper( PersonNameMapper.class ); - @Mapping(source = "name", target = "fulName") + @Mapping(target = "fulName", source = "name") Person mapPerson(PersonDto dto); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/Break.java b/processor/src/test/java/org/mapstruct/ap/test/naming/Break.java index 003eefbc84..c9335aa4b1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/Break.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/Break.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming; diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/Source.java b/processor/src/test/java/org/mapstruct/ap/test/naming/Source.java index 241edcee46..0fe5629a1f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming; diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/naming/SourceTargetMapper.java index 99c32d7bae..d1d702e2ee 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming; diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/VariableNamingTest.java b/processor/src/test/java/org/mapstruct/ap/test/naming/VariableNamingTest.java index df69782e14..a8e833ee06 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/VariableNamingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/VariableNamingTest.java @@ -1,37 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.entry; - import java.util.Arrays; +import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.HashMap; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.ReadsDefaultTimeZone; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.entry; /** * Test for naming of variables/members which conflict with keywords or parameter names. @@ -40,19 +27,19 @@ */ @WithClasses({ SourceTargetMapper.class, While.class, Break.class, Source.class }) @IssueKey("53") -@RunWith(AnnotationProcessorTestRunner.class) +@ReadsDefaultTimeZone public class VariableNamingTest { - @Test + @ProcessorTest public void shouldGenerateImplementationsOfMethodsWithProblematicVariableNmes() { Source source = new Source(); source.setSomeNumber( 42 ); - source.setValues( Arrays.asList( 42L, 121L ) ); + source.setValues( Arrays.asList( 42L, 121L ) ); - Map map = new HashMap(); - map.put( 42L, new GregorianCalendar( 1980, 0, 1 ).getTime() ); - map.put( 121L, new GregorianCalendar( 2013, 6, 20 ).getTime() ); + Map map = new HashMap<>(); + map.put( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() ); + map.put( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() ); source.setMap( map ); Break target = SourceTargetMapper.INSTANCE.sourceToBreak( source ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/While.java b/processor/src/test/java/org/mapstruct/ap/test/naming/While.java index 02f4a5e029..b91bed5e24 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/While.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/While.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming; diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomAccessorNamingStrategy.java b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomAccessorNamingStrategy.java index 763d638f49..21352396d0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomAccessorNamingStrategy.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomAccessorNamingStrategy.java @@ -1,30 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming.spi; -import java.beans.Introspector; - import javax.lang.model.element.ExecutableElement; import javax.lang.model.type.TypeKind; import org.mapstruct.ap.spi.AccessorNamingStrategy; import org.mapstruct.ap.spi.DefaultAccessorNamingStrategy; +import org.mapstruct.ap.spi.util.IntrospectorUtils; /** * A custom {@link AccessorNamingStrategy} recognizing getters in the form of {@code property()} and setters in the @@ -55,13 +41,14 @@ public boolean isAdderMethod(ExecutableElement method) { @Override public String getPropertyName(ExecutableElement getterOrSetterMethod) { String methodName = getterOrSetterMethod.getSimpleName().toString(); - return Introspector.decapitalize( methodName.startsWith( "with" ) ? methodName.substring( 4 ) : methodName ); + return IntrospectorUtils.decapitalize( + methodName.startsWith( "with" ) ? methodName.substring( 4 ) : methodName ); } @Override public String getElementName(ExecutableElement adderMethod) { String methodName = adderMethod.getSimpleName().toString(); - return Introspector.decapitalize( methodName.substring( 3 ) ); + return IntrospectorUtils.decapitalize( methodName.substring( 3 ) ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomNamingStrategyTest.java b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomNamingStrategyTest.java index f450a9ebb5..78608dd7ba 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomNamingStrategyTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/CustomNamingStrategyTest.java @@ -1,42 +1,26 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming.spi; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.spi.AccessorNamingStrategy; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithServiceImplementation; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test do demonstrate the usage of custom implementations of {@link AccessorNamingStrategy}. * * @author Andreas Gudian */ -@RunWith(AnnotationProcessorTestRunner.class) @WithClasses({ GolfPlayer.class, GolfPlayerDto.class, GolfPlayerMapper.class }) @WithServiceImplementation(CustomAccessorNamingStrategy.class) public class CustomNamingStrategyTest { - @Test + @ProcessorTest public void shouldApplyCustomNamingStrategy() { GolfPlayer player = new GolfPlayer() .withName( "Jared" ) diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayer.java b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayer.java index 22ed2953de..fa0af60de9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming.spi; diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerDto.java b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerDto.java index 0b8c6a87b9..bd9c4ecf8c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming.spi; diff --git a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerMapper.java index d4c97fd80c..bcfd923240 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/naming/spi/GolfPlayerMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.naming.spi; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Car.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Car.java index 5390171055..f89a35d830 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Car.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; import java.util.List; +import java.util.Objects; public class Car { @@ -73,10 +61,10 @@ public boolean equals(Object o) { if ( year != car.year ) { return false; } - if ( name != null ? !name.equals( car.name ) : car.name != null ) { + if ( !Objects.equals( name, car.name ) ) { return false; } - return wheels != null ? wheels.equals( car.wheels ) : car.wheels == null; + return Objects.equals( wheels, car.wheels ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/CarDto.java index eb3cf1d6eb..1eed692016 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/CarDto.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; import java.util.List; +import java.util.Objects; public class CarDto { @@ -73,10 +61,10 @@ public boolean equals(Object o) { if ( year != carDto.year ) { return false; } - if ( name != null ? !name.equals( carDto.name ) : carDto.name != null ) { + if ( !Objects.equals( name, carDto.name ) ) { return false; } - return wheels != null ? wheels.equals( carDto.wheels ) : carDto.wheels == null; + return Objects.equals( wheels, carDto.wheels ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisableConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisableConfig.java index 8c49d6090e..5a346c672d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisableConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisableConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisablingNestedSimpleBeansMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisablingNestedSimpleBeansMappingTest.java index 2452936082..7331a5cc2d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisablingNestedSimpleBeansMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DisablingNestedSimpleBeansMappingTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -35,7 +20,6 @@ Roof.class, RoofDto.class, RoofType.class, ExternalRoofType.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class DisablingNestedSimpleBeansMappingTest { @WithClasses({ @@ -45,13 +29,13 @@ public class DisablingNestedSimpleBeansMappingTest { diagnostics = { @Diagnostic(type = ErroneousDisabledHouseMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \".*\\.Roof roof\" to \".*\\.RoofDto roof\"\\. Consider to " + - "declare/implement a mapping method: \".*\\.RoofDto map\\(.*\\.Roof value\\)\"\\." + line = 16, + message = "Can't map property \"Roof roof\" to \"RoofDto roof\". " + + "Consider to declare/implement a mapping method: \"RoofDto map(Roof value)\"." ) }) - @Test - public void shouldUseDisabledMethodGenerationOnMapper() throws Exception { + @ProcessorTest + public void shouldUseDisabledMethodGenerationOnMapper() { } @WithClasses({ @@ -62,12 +46,12 @@ public void shouldUseDisabledMethodGenerationOnMapper() throws Exception { diagnostics = { @Diagnostic(type = ErroneousDisabledViaConfigHouseMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \".*\\.Roof roof\" to \".*\\.RoofDto roof\"\\. Consider to " + - "declare/implement a mapping method: \".*\\.RoofDto map\\(.*\\.Roof value\\)\"\\." + line = 16, + message = "Can't map property \"Roof roof\" to \"RoofDto roof\". " + + "Consider to declare/implement a mapping method: \"RoofDto map(Roof value)\"." ) }) - @Test - public void shouldUseDisabledMethodGenerationOnMapperConfig() throws Exception { + @ProcessorTest + public void shouldUseDisabledMethodGenerationOnMapperConfig() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java index 4fbf16812e..571f3feade 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/DottedErrorMessageTest.java @@ -1,83 +1,80 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; -import org.junit.Test; - -import org.junit.runner.RunWith; import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.Car; +import org.mapstruct.ap.test.nestedbeans.unmappable.CarDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Cat; +import org.mapstruct.ap.test.nestedbeans.unmappable.CatDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Color; +import org.mapstruct.ap.test.nestedbeans.unmappable.ColorDto; import org.mapstruct.ap.test.nestedbeans.unmappable.Computer; import org.mapstruct.ap.test.nestedbeans.unmappable.ComputerDto; import org.mapstruct.ap.test.nestedbeans.unmappable.Dictionary; import org.mapstruct.ap.test.nestedbeans.unmappable.DictionaryDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.ExternalRoofType; import org.mapstruct.ap.test.nestedbeans.unmappable.ForeignWord; import org.mapstruct.ap.test.nestedbeans.unmappable.ForeignWordDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Cat; -import org.mapstruct.ap.test.nestedbeans.unmappable.CatDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.House; +import org.mapstruct.ap.test.nestedbeans.unmappable.HouseDto; import org.mapstruct.ap.test.nestedbeans.unmappable.Info; import org.mapstruct.ap.test.nestedbeans.unmappable.InfoDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Roof; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofType; import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableCollectionElementPropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableDeepListMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableDeepMapKeyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableDeepMapValueMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableEnumMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.User; +import org.mapstruct.ap.test.nestedbeans.unmappable.UserDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Wheel; +import org.mapstruct.ap.test.nestedbeans.unmappable.WheelDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Word; +import org.mapstruct.ap.test.nestedbeans.unmappable.WordDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceEnumMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableSourceValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableTargetCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableTargetDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableTargetDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableTargetDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableTargetDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableTargetValuePropertyMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.ignore.UnmappableIgnoreCollectionElementPropertyMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.ignore.UnmappableIgnoreDeepListMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.ignore.UnmappableIgnoreDeepMapKeyMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.ignore.UnmappableIgnoreDeepMapValueMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.ignore.UnmappableIgnoreDeepNestingMapper; import org.mapstruct.ap.test.nestedbeans.unmappable.ignore.UnmappableIgnoreValuePropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableWarnCollectionElementPropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableWarnDeepListMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableWarnDeepMapKeyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableWarnDeepMapValueMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableWarnDeepNestingMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableWarnValuePropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.UserDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.User; -import org.mapstruct.ap.test.nestedbeans.unmappable.WheelDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Wheel; -import org.mapstruct.ap.test.nestedbeans.unmappable.Car; -import org.mapstruct.ap.test.nestedbeans.unmappable.CarDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.ExternalRoofType; -import org.mapstruct.ap.test.nestedbeans.unmappable.House; -import org.mapstruct.ap.test.nestedbeans.unmappable.HouseDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Color; -import org.mapstruct.ap.test.nestedbeans.unmappable.ColorDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Roof; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofType; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.erroneous.UnmappableDeepNestingMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.Word; -import org.mapstruct.ap.test.nestedbeans.unmappable.WordDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableSourceWarnCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableSourceWarnDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableSourceWarnDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableSourceWarnDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableSourceWarnDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableSourceWarnValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableTargetWarnCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableTargetWarnDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableTargetWarnDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableTargetWarnDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableTargetWarnDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.warn.UnmappableTargetWarnValuePropertyMapper; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; @WithClasses({ Car.class, CarDto.class, Color.class, ColorDto.class, @@ -95,7 +92,6 @@ BaseDeepNestingMapper.class, BaseValuePropertyMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class DottedErrorMessageTest { private static final String PROPERTY = "property"; @@ -103,177 +99,356 @@ public class DottedErrorMessageTest { private static final String MAP_KEY = "Map key"; private static final String MAP_VALUE = "Map value"; - @Test + @ProcessorTest + @WithClasses({ + UnmappableTargetDeepNestingMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableTargetDeepNestingMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 14, + message = "Unmapped target property: \"rgb\". Mapping from " + PROPERTY + + " \"Color house.roof.color\" to \"ColorDto house.roof.color\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepNestingMapper'.") + } + ) + public void testTargetDeepNestedBeans() { + } + + @ProcessorTest + @WithClasses({ + UnmappableTargetDeepListMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableTargetDeepListMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 14, + message = "Unmapped target property: \"left\". Mapping from " + COLLECTION_ELEMENT + + " \"Wheel car.wheels\" to \"WheelDto car.wheels\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepListMapper'.") + } + ) + public void testTargetIterables() { + } + + @ProcessorTest @WithClasses({ - UnmappableDeepNestingMapper.class + UnmappableTargetDeepMapKeyMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = BaseDeepNestingMapper.class, + @Diagnostic(type = UnmappableTargetDeepMapKeyMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 23, - messageRegExp = "Unmapped target property: \"rgb\"\\. Mapping from " + PROPERTY + - " \".*Color house\\.roof\\.color\" to \".*ColorDto house\\.roof\\.color\"\\.") + line = 14, + message = "Unmapped target property: \"pronunciation\". Mapping from " + MAP_KEY + + " \"Word dictionary.wordMap{:key}\" to \"WordDto dictionary.wordMap{:key}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapKeyMapper'.") } ) - public void testDeepNestedBeans() { + public void testTargetMapKeys() { } - @Test + @ProcessorTest @WithClasses({ - UnmappableDeepListMapper.class + UnmappableTargetDeepMapValueMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = BaseDeepListMapper.class, + @Diagnostic(type = UnmappableTargetDeepMapValueMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 23, - messageRegExp = "Unmapped target property: \"left\"\\. Mapping from " + COLLECTION_ELEMENT + - " \".*Wheel car\\.wheels\" to \".*WheelDto car\\.wheels\"\\.") + line = 14, + message = "Unmapped target property: \"pronunciation\". Mapping from " + MAP_VALUE + + " \"ForeignWord dictionary.wordMap{:value}\" to \"ForeignWordDto dictionary.wordMap{:value}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapValueMapper'.") } ) - public void testIterables() { + public void testTargetMapValues() { } - @Test + @ProcessorTest @WithClasses({ - UnmappableDeepMapKeyMapper.class + UnmappableTargetCollectionElementPropertyMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = BaseDeepMapKeyMapper.class, + @Diagnostic(type = UnmappableTargetCollectionElementPropertyMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 23, - messageRegExp = "Unmapped target property: \"pronunciation\"\\. Mapping from " + MAP_KEY + - " \".*Word dictionary\\.wordMap\\{:key\\}\" to \".*WordDto dictionary\\.wordMap\\{:key\\}\"\\.") + line = 14, + message = "Unmapped target property: \"color\". Mapping from " + PROPERTY + + " \"Info computers[].info\" to \"InfoDto computers[].info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseCollectionElementPropertyMapper'.") } ) - public void testMapKeys() { + public void testTargetCollectionElementProperty() { } - @Test + @ProcessorTest @WithClasses({ - UnmappableDeepMapValueMapper.class + UnmappableTargetValuePropertyMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = BaseDeepMapValueMapper.class, + @Diagnostic(type = UnmappableTargetValuePropertyMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 23, - messageRegExp = "Unmapped target property: \"pronunciation\"\\. Mapping from " + MAP_VALUE + - " \".*ForeignWord dictionary\\.wordMap\\{:value\\}\" " + - "to \".*ForeignWordDto dictionary\\.wordMap\\{:value\\}\"\\.") + line = 14, + message = "Unmapped target property: \"color\". Mapping from " + PROPERTY + + " \"Info catNameMap{:value}.info\" to \"InfoDto catNameMap{:value}.info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseValuePropertyMapper'.") } ) - public void testMapValues() { + public void testTargetMapValueProperty() { } - @Test + @IssueKey( "2788" ) + @ProcessorTest @WithClasses({ - UnmappableCollectionElementPropertyMapper.class + UnmappableSourceDeepNestingMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = BaseCollectionElementPropertyMapper.class, + @Diagnostic(type = UnmappableSourceDeepNestingMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 23, - messageRegExp = "Unmapped target property: \"color\"\\. Mapping from " + PROPERTY + - " \".*Info computers\\[\\].info\" to \".*InfoDto computers\\[\\].info\"\\.") + line = 16, + message = "Unmapped source property: \"cmyk\". Mapping from " + PROPERTY + + " \"Color house.roof.color\" to \"ColorDto house.roof.color\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepNestingMapper'.") } ) - public void testCollectionElementProperty() { + public void testSourceDeepNestedBeans() { } - @Test + @IssueKey( "2788" ) + @ProcessorTest @WithClasses({ - UnmappableValuePropertyMapper.class + UnmappableSourceDeepListMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = BaseValuePropertyMapper.class, + @Diagnostic(type = UnmappableSourceDeepListMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 23, - messageRegExp = "Unmapped target property: \"color\"\\. Mapping from " + PROPERTY + - " \".*Info catNameMap\\{:value\\}.info\" to \".*InfoDto catNameMap\\{:value\\}.info\"\\.") + line = 16, + message = "Unmapped source property: \"right\". Mapping from " + COLLECTION_ELEMENT + + " \"Wheel car.wheels\" to \"WheelDto car.wheels\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepListMapper'.") } ) - public void testMapValueProperty() { + public void testSourceIterables() { } - @Test + @IssueKey( "2788" ) + @ProcessorTest @WithClasses({ - UnmappableEnumMapper.class + UnmappableSourceDeepMapKeyMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { - @Diagnostic(type = UnmappableEnumMapper.class, + @Diagnostic(type = UnmappableSourceDeepMapKeyMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 38, - messageRegExp = "The following constants from the property \".*RoofType house\\.roof\\.type\" enum " + - "have no corresponding constant in the \".*ExternalRoofType house\\.roof\\.type\" enum and must " + - "be be mapped via adding additional mappings: NORMAL\\." + line = 16, + message = "Unmapped source property: \"meaning\". Mapping from " + MAP_KEY + + " \"Word dictionary.wordMap{:key}\" to \"WordDto dictionary.wordMap{:key}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapKeyMapper'.") + } + ) + public void testSourceMapKeys() { + } + + @IssueKey( "2788" ) + @ProcessorTest + @WithClasses({ + UnmappableSourceDeepMapValueMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableSourceDeepMapValueMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Unmapped source property: \"meaning\". Mapping from " + MAP_VALUE + + " \"ForeignWord dictionary.wordMap{:value}\" to \"ForeignWordDto dictionary.wordMap{:value}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapValueMapper'.") + } + ) + public void testSourceMapValues() { + } + + @IssueKey( "2788" ) + @ProcessorTest + @WithClasses({ + UnmappableSourceCollectionElementPropertyMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableSourceCollectionElementPropertyMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Unmapped source property: \"size\". Mapping from " + PROPERTY + + " \"Info computers[].info\" to \"InfoDto computers[].info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseCollectionElementPropertyMapper'.") + } + ) + public void testSourceCollectionElementProperty() { + } + + @IssueKey( "2788" ) + @ProcessorTest + @WithClasses({ + UnmappableSourceValuePropertyMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableSourceValuePropertyMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 16, + message = "Unmapped source property: \"size\". Mapping from " + PROPERTY + + " \"Info catNameMap{:value}.info\" to \"InfoDto catNameMap{:value}.info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseValuePropertyMapper'.") + } + ) + public void testSourceMapValueProperty() { + } + + @ProcessorTest + @WithClasses({ + UnmappableSourceEnumMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = UnmappableSourceEnumMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 25, + message = + "The following constants from the property \"RoofType house.roof.type\" enum " + + "have no corresponding constant in the \"ExternalRoofType house.roof.type\" enum and must " + + "be be mapped via adding additional mappings: NORMAL." ) } ) - public void testMapEnumProperty() { + public void testSourceMapEnumProperty() { } - @Test + @ProcessorTest @WithClasses({ - UnmappableWarnDeepNestingMapper.class, - UnmappableWarnDeepListMapper.class, - UnmappableWarnDeepMapKeyMapper.class, - UnmappableWarnDeepMapValueMapper.class, - UnmappableWarnCollectionElementPropertyMapper.class, - UnmappableWarnValuePropertyMapper.class + UnmappableTargetWarnDeepNestingMapper.class, + UnmappableTargetWarnDeepListMapper.class, + UnmappableTargetWarnDeepMapKeyMapper.class, + UnmappableTargetWarnDeepMapValueMapper.class, + UnmappableTargetWarnCollectionElementPropertyMapper.class, + UnmappableTargetWarnValuePropertyMapper.class }) @ExpectedCompilationOutcome( value = CompilationResult.SUCCEEDED, diagnostics = { - @Diagnostic(type = BaseDeepNestingMapper.class, + @Diagnostic(type = UnmappableTargetWarnDeepNestingMapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 23, - messageRegExp = "Unmapped target property: \"rgb\"\\. Mapping from " + PROPERTY + - " \".*Color house\\.roof\\.color\" to \".*ColorDto house\\.roof\\.color\"\\."), - @Diagnostic(type = BaseDeepListMapper.class, + line = 16, + message = "Unmapped target property: \"rgb\". Mapping from " + PROPERTY + + " \"Color house.roof.color\" to \"ColorDto house.roof.color\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepNestingMapper'."), + @Diagnostic(type = UnmappableTargetWarnDeepListMapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 23, - messageRegExp = "Unmapped target property: \"left\"\\. Mapping from " + COLLECTION_ELEMENT + - " \".*Wheel car\\.wheels\" to \".*WheelDto car\\.wheels\"\\."), - @Diagnostic(type = BaseDeepMapKeyMapper.class, + line = 16, + message = "Unmapped target property: \"left\". Mapping from " + COLLECTION_ELEMENT + + " \"Wheel car.wheels\" to \"WheelDto car.wheels\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepListMapper'."), + @Diagnostic(type = UnmappableTargetWarnDeepMapKeyMapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 23, - messageRegExp = "Unmapped target property: \"pronunciation\"\\. Mapping from " + MAP_KEY + - " \".*Word dictionary\\.wordMap\\{:key\\}\" to \".*WordDto dictionary\\.wordMap\\{:key\\}\"\\."), - @Diagnostic(type = BaseDeepMapValueMapper.class, + line = 16, + message = "Unmapped target property: \"pronunciation\". Mapping from " + MAP_KEY + + " \"Word dictionary.wordMap{:key}\" to \"WordDto dictionary.wordMap{:key}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapKeyMapper'."), + @Diagnostic(type = UnmappableTargetWarnDeepMapValueMapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 23, - messageRegExp = "Unmapped target property: \"pronunciation\"\\. Mapping from " + MAP_VALUE + - " \".*ForeignWord dictionary\\.wordMap\\{:value\\}\" " + - "to \".*ForeignWordDto dictionary\\.wordMap\\{:value\\}\"\\."), - @Diagnostic(type = BaseCollectionElementPropertyMapper.class, + line = 16, + message = "Unmapped target property: \"pronunciation\". Mapping from " + MAP_VALUE + + " \"ForeignWord dictionary.wordMap{:value}\" to \"ForeignWordDto dictionary.wordMap{:value}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapValueMapper'."), + @Diagnostic(type = UnmappableTargetWarnCollectionElementPropertyMapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 23, - messageRegExp = "Unmapped target property: \"color\"\\. Mapping from " + PROPERTY + - " \".*Info computers\\[\\].info\" to \".*InfoDto computers\\[\\].info\"\\."), - @Diagnostic(type = BaseValuePropertyMapper.class, + line = 16, + message = "Unmapped target property: \"color\". Mapping from " + PROPERTY + + " \"Info computers[].info\" to \"InfoDto computers[].info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseCollectionElementPropertyMapper'."), + @Diagnostic(type = UnmappableTargetWarnValuePropertyMapper.class, kind = javax.tools.Diagnostic.Kind.WARNING, - line = 23, - messageRegExp = "Unmapped target property: \"color\"\\. Mapping from " + PROPERTY + - " \".*Info catNameMap\\{:value\\}.info\" to \".*InfoDto catNameMap\\{:value\\}.info\"\\.") + line = 16, + message = "Unmapped target property: \"color\". Mapping from " + PROPERTY + + " \"Info catNameMap{:value}.info\" to \"InfoDto catNameMap{:value}.info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseValuePropertyMapper'.") } ) public void testWarnUnmappedTargetProperties() { } - @Test + @IssueKey( "2788" ) + @ProcessorTest + @WithClasses({ + UnmappableSourceWarnDeepNestingMapper.class, + UnmappableSourceWarnDeepListMapper.class, + UnmappableSourceWarnDeepMapKeyMapper.class, + UnmappableSourceWarnDeepMapValueMapper.class, + UnmappableSourceWarnCollectionElementPropertyMapper.class, + UnmappableSourceWarnValuePropertyMapper.class + }) + @ExpectedCompilationOutcome( + value = CompilationResult.SUCCEEDED, + diagnostics = { + @Diagnostic(type = UnmappableSourceWarnDeepNestingMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 16, + message = "Unmapped source property: \"cmyk\". Mapping from " + PROPERTY + + " \"Color house.roof.color\" to \"ColorDto house.roof.color\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepNestingMapper'."), + @Diagnostic(type = UnmappableSourceWarnDeepListMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 16, + message = "Unmapped source property: \"right\". Mapping from " + COLLECTION_ELEMENT + + " \"Wheel car.wheels\" to \"WheelDto car.wheels\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepListMapper'."), + @Diagnostic(type = UnmappableSourceWarnDeepMapKeyMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 16, + message = "Unmapped source property: \"meaning\". Mapping from " + MAP_KEY + + " \"Word dictionary.wordMap{:key}\" to \"WordDto dictionary.wordMap{:key}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapKeyMapper'."), + @Diagnostic(type = UnmappableSourceWarnDeepMapValueMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 16, + message = "Unmapped source property: \"meaning\". Mapping from " + MAP_VALUE + + " \"ForeignWord dictionary.wordMap{:value}\" to \"ForeignWordDto dictionary.wordMap{:value}\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseDeepMapValueMapper'."), + @Diagnostic(type = UnmappableSourceWarnCollectionElementPropertyMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 16, + message = "Unmapped source property: \"size\". Mapping from " + PROPERTY + + " \"Info computers[].info\" to \"InfoDto computers[].info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseCollectionElementPropertyMapper'."), + @Diagnostic(type = UnmappableSourceWarnValuePropertyMapper.class, + kind = javax.tools.Diagnostic.Kind.WARNING, + line = 16, + message = "Unmapped source property: \"size\". Mapping from " + PROPERTY + + " \"Info catNameMap{:value}.info\" to \"InfoDto catNameMap{:value}.info\"." + + " Occured at 'UserDto userToUserDto(User user)' in 'BaseValuePropertyMapper'.") + } + ) + public void testWarnUnmappedSourceProperties() { + } + + @ProcessorTest @WithClasses({ UnmappableIgnoreDeepNestingMapper.class, UnmappableIgnoreDeepListMapper.class, diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledHouseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledHouseMapper.java index d5617b70f5..5780d83252 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledHouseMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledHouseMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledViaConfigHouseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledViaConfigHouseMapper.java index ff5ceabf3b..cbaf3cbe18 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledViaConfigHouseMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ErroneousDisabledViaConfigHouseMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java index 9f86ca22c6..adfd4a26b3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/ExternalRoofType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/House.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/House.java index dd4bb6b71a..8badaae653 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/House.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/House.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; +import java.util.Objects; + public class House { private String name; @@ -73,10 +62,10 @@ public boolean equals(Object o) { if ( year != house.year ) { return false; } - if ( name != null ? !name.equals( house.name ) : house.name != null ) { + if ( !Objects.equals( name, house.name ) ) { return false; } - return roof != null ? roof.equals( house.roof ) : house.roof == null; + return Objects.equals( roof, house.roof ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/HouseDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/HouseDto.java index 8007534228..71beedaa93 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/HouseDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/HouseDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; +import java.util.Objects; + public class HouseDto { private String name; @@ -71,10 +60,10 @@ public boolean equals(Object o) { if ( year != houseDto.year ) { return false; } - if ( name != null ? !name.equals( houseDto.name ) : houseDto.name != null ) { + if ( !Objects.equals( name, houseDto.name ) ) { return false; } - return roof != null ? roof.equals( houseDto.roof ) : houseDto.roof == null; + return Objects.equals( roof, houseDto.roof ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/MultipleForgedMethodsTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/MultipleForgedMethodsTest.java index 33d0b855e2..9231ed46e2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/MultipleForgedMethodsTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/MultipleForgedMethodsTest.java @@ -1,26 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; +import java.util.Arrays; +import java.util.HashMap; + import org.mapstruct.ap.test.nestedbeans.maps.AntonymsDictionary; import org.mapstruct.ap.test.nestedbeans.maps.AntonymsDictionaryDto; import org.mapstruct.ap.test.nestedbeans.maps.AutoMapMapper; @@ -29,26 +16,24 @@ import org.mapstruct.ap.test.nestedbeans.multiplecollections.Garage; import org.mapstruct.ap.test.nestedbeans.multiplecollections.GarageDto; import org.mapstruct.ap.test.nestedbeans.multiplecollections.MultipleListMapper; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -import java.util.Arrays; -import java.util.HashMap; +import static org.junit.jupiter.api.Assertions.assertEquals; /** * This test is for a case when several identical methods could be generated, what is an easy edge case to miss. */ -@RunWith(AnnotationProcessorTestRunner.class) public class MultipleForgedMethodsTest { @WithClasses({ Word.class, WordDto.class, AntonymsDictionaryDto.class, AntonymsDictionary.class, AutoMapMapper.class }) - @Test + @ProcessorTest public void testNestedMapsAutoMap() { - HashMap dtoAntonyms = new HashMap(); - HashMap entityAntonyms = new HashMap(); + HashMap dtoAntonyms = new HashMap<>(); + HashMap entityAntonyms = new HashMap<>(); String[] words = { "black", "good", "up", "left", "fast" }; String[] antonyms = { "white", "bad", "down", "right", "slow" }; @@ -65,8 +50,10 @@ public void testNestedMapsAutoMap() { AntonymsDictionary mappedAntonymsDictionary = AutoMapMapper.INSTANCE.entityToDto( new AntonymsDictionaryDto( dtoAntonyms ) ); - Assert.assertEquals( "Mapper did not map dto to entity correctly", new AntonymsDictionary( entityAntonyms ), - mappedAntonymsDictionary + assertEquals( + new AntonymsDictionary( entityAntonyms ), + mappedAntonymsDictionary, + "Mapper did not map dto to entity correctly" ); } @@ -74,7 +61,7 @@ public void testNestedMapsAutoMap() { MultipleListMapper.class, Garage.class, GarageDto.class, Car.class, CarDto.class, Wheel.class, WheelDto.class }) - @Test + @ProcessorTest public void testMultipleCollections() { GarageDto dto = new GarageDto( Arrays.asList( new CarDto( @@ -110,7 +97,7 @@ public void testMultipleCollections() { GarageDto mappedDto = MultipleListMapper.INSTANCE.convert( entity ); - Assert.assertEquals( "Mapper did not map entity to dto correctly", dto, mappedDto ); + assertEquals( dto, mappedDto, "Mapper did not map entity to dto correctly" ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java index 3ce4fe9804..b78da21860 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/NestedSimpleBeansMappingTest.java @@ -1,33 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; import java.util.List; -import java.util.function.Function; import java.util.stream.Collectors; import org.assertj.core.groups.Tuple; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; @@ -47,18 +31,17 @@ UserDtoMapperSmart.class, UserDtoUpdateMapperSmart.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class NestedSimpleBeansMappingTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( UserDtoMapperClassic.class, UserDtoMapperSmart.class, UserDtoUpdateMapperSmart.class ); - @Test - public void shouldHaveAllFields() throws Exception { + @ProcessorTest + public void shouldHaveAllFields() { // If this test fails that means something new was added to the structure of the User/UserDto. // Make sure that the other tests are also updated (the new field is asserted) String[] userFields = new String[] { "name", "car", "secondCar", "house" }; @@ -82,7 +65,7 @@ public void shouldHaveAllFields() throws Exception { assertThat( RoofDto.class ).hasOnlyDeclaredFields( roofFields ); } - @Test + @ProcessorTest public void shouldMapNestedBeans() { User user = TestData.createUser(); @@ -94,7 +77,7 @@ public void shouldMapNestedBeans() { assertUserDto( smartMapping, user ); } - @Test + @ProcessorTest public void shouldMapUpdateNestedBeans() { User user = TestData.createUser(); @@ -111,7 +94,7 @@ public void shouldMapUpdateNestedBeans() { // result assertThat( smartMapping.getName() ).isEqualTo( user.getName() ); assertThat( smartMapping.getCar().getYear() ).isEqualTo( user.getCar().getYear() ); - assertThat( smartMapping.getCar().getName() ).isEqualTo( "Toyota" ); + assertThat( smartMapping.getCar().getName() ).isNull(); assertThat( user.getCar().getName() ).isNull(); assertWheels( smartMapping.getCar().getWheels(), user.getCar().getWheels() ); assertCar( smartMapping.getSecondCar(), user.getSecondCar() ); @@ -138,12 +121,9 @@ private static void assertCar(CarDto carDto, Car car) { } private static void assertWheels(List wheelDtos, List wheels) { - List wheelTuples = wheels.stream().map( new Function() { - @Override - public Tuple apply(Wheel wheel) { - return tuple( wheel.isFront(), wheel.isRight() ); - } - } ).collect( Collectors.toList() ); + List wheelTuples = wheels.stream() + .map( wheel -> tuple( wheel.isFront(), wheel.isRight() ) ) + .collect( Collectors.toList() ); assertThat( wheelDtos ) .extracting( "front", "right" ) .containsExactlyElementsOf( wheelTuples ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RecursionTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RecursionTest.java index 97eb5b0661..861b1a01b9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RecursionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RecursionTest.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; @@ -22,24 +9,21 @@ import java.util.Iterator; import java.util.List; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.nestedbeans.recursive.RecursionMapper; import org.mapstruct.ap.test.nestedbeans.recursive.TreeRecursionMapper; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; -@RunWith(AnnotationProcessorTestRunner.class) public class RecursionTest { @WithClasses({ RecursionMapper.class }) - @Test + @ProcessorTest @IssueKey("1103") public void testRecursiveAutoMap() { RecursionMapper.RootDto rootDto = new RecursionMapper.RootDto( @@ -53,7 +37,7 @@ public void testRecursiveAutoMap() { } private void assertRootEquals(RecursionMapper.RootDto rootDto, RecursionMapper.Root root) { - if (bothNull( root, rootDto )) { + if ( bothNull( root, rootDto ) ) { return; } assertNotNull( root ); @@ -74,7 +58,7 @@ private void assertChildEquals(RecursionMapper.ChildDto childDto, RecursionMappe @WithClasses({ TreeRecursionMapper.class }) - @Test + @ProcessorTest @IssueKey("1103") public void testRecursiveTreeAutoMap() { TreeRecursionMapper.RootDto rootDto = new TreeRecursionMapper.RootDto( @@ -94,7 +78,7 @@ public void testRecursiveTreeAutoMap() { } private void assertTreeRootEquals(TreeRecursionMapper.RootDto rootDto, TreeRecursionMapper.Root root) { - if (bothNull( root, rootDto )) { + if ( bothNull( root, rootDto ) ) { return; } assertNotNull( root ); @@ -104,7 +88,7 @@ private void assertTreeRootEquals(TreeRecursionMapper.RootDto rootDto, TreeRecur private void assertChildrenEqual(List childrenDto, List children) { - if (bothNull( children, childrenDto )) { + if ( bothNull( children, childrenDto ) ) { return; } assertNotNull( childrenDto ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java index e3c98cbb65..6e94c50e60 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Roof.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java index c999cd10bb..5721d3f6f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; +import java.util.Objects; + public class RoofDto { private String color; private ExternalRoofType type; @@ -61,7 +50,7 @@ public boolean equals(Object o) { return false; } - return color != null ? color.equals( roofDto.color ) : roofDto.color == null; + return Objects.equals( color, roofDto.color ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java index 91abcb366f..7d2b999a95 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/RoofType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java index 3335e367ec..02620920f7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/TestData.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java index 6b50b65f31..11ffc5b889 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/User.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; +import java.util.Objects; + public class User { private String name; @@ -77,13 +66,13 @@ public boolean equals(Object o) { User user = (User) o; - if ( name != null ? !name.equals( user.name ) : user.name != null ) { + if ( !Objects.equals( name, user.name ) ) { return false; } - if ( car != null ? !car.equals( user.car ) : user.car != null ) { + if ( !Objects.equals( car, user.car ) ) { return false; } - return house != null ? house.equals( user.house ) : user.house == null; + return Objects.equals( house, user.house ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java index a36b08ca09..c496e23529 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; +import java.util.Objects; + public class UserDto { private String name; @@ -77,13 +66,13 @@ public boolean equals(Object o) { UserDto userDto = (UserDto) o; - if ( name != null ? !name.equals( userDto.name ) : userDto.name != null ) { + if ( !Objects.equals( name, userDto.name ) ) { return false; } - if ( car != null ? !car.equals( userDto.car ) : userDto.car != null ) { + if ( !Objects.equals( car, userDto.car ) ) { return false; } - return house != null ? house.equals( userDto.house ) : userDto.house == null; + return Objects.equals( house, userDto.house ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java index d461d90d83..8c1c6925b9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperClassic.java @@ -1,28 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; +import java.util.List; + import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; -import java.util.List; - @Mapper public interface UserDtoMapperClassic { diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java index 90e5322cc1..8019a7cb36 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoMapperSmart.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmart.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmart.java index adc1a43adf..cee32323ae 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmart.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/UserDtoUpdateMapperSmart.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Wheel.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Wheel.java index d97458ce4b..00c84f6e2b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Wheel.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/Wheel.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/WheelDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/WheelDto.java index c5494fb591..63d0c58a3a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/WheelDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/WheelDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/EntityFactory.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/EntityFactory.java index 7302445e51..6e0c5fd957 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/EntityFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/EntityFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions; @@ -34,10 +21,7 @@ public T createEntity(@TargetType Class entityClass) throws MappingExcept try { entity = entityClass.newInstance(); } - catch ( IllegalAccessException exception ) { - throw new MappingException( "Rare exception thrown, refer to stack trace", exception ); - } - catch ( InstantiationException exception ) { + catch ( IllegalAccessException | InstantiationException exception ) { throw new MappingException( "Rare exception thrown, refer to stack trace", exception ); } catch ( Exception exception ) { diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/MappingException.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/MappingException.java index 7e72786ff7..233c434342 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/MappingException.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/MappingException.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/NestedMappingsWithExceptionTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/NestedMappingsWithExceptionTest.java index acb1353453..2a5f10ad22 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/NestedMappingsWithExceptionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/NestedMappingsWithExceptionTest.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.nestedbeans.exceptions._target.DeveloperDto; import org.mapstruct.ap.test.nestedbeans.exceptions._target.ProjectDto; import org.mapstruct.ap.test.nestedbeans.exceptions.source.Developer; import org.mapstruct.ap.test.nestedbeans.exceptions.source.Project; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -41,10 +26,9 @@ EntityFactory.class }) @IssueKey("1304") -@RunWith(AnnotationProcessorTestRunner.class) public class NestedMappingsWithExceptionTest { - @Test + @ProcessorTest public void shouldGenerateCodeThatCompiles() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/ProjectMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/ProjectMapper.java index 58ce299738..a2b836dc6f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/ProjectMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/ProjectMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/DeveloperDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/DeveloperDto.java index c813bca133..2fd0b03d4c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/DeveloperDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/DeveloperDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/ProjectDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/ProjectDto.java index 9cd1386ca6..b8fc7e0e3f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/ProjectDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/_target/ProjectDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Developer.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Developer.java index 6c453480e0..6f0318e028 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Developer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Developer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Project.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Project.java index 8b5e0771ef..e302a79c96 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Project.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exceptions/source/Project.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exceptions.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalMapper.java index 842199c466..111aca1099 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalTest.java index b367dbf57f..ae4a7d945a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/ErroneousJavaInternalTest.java @@ -1,31 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -35,7 +20,6 @@ Target.class, ErroneousJavaInternalMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1154") public class ErroneousJavaInternalTest { @@ -43,29 +27,28 @@ public class ErroneousJavaInternalTest { diagnostics = { @Diagnostic(type = ErroneousJavaInternalMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \".*MyType date\" to \"java\\.util\\.Date date\"\\. Consider to " + - "declare/implement a mapping method: \"java\\.util\\.Date map\\(.*MyType value\\)\"\\."), + line = 16, + message = "Can't map property \"Source.MyType date\" to \"Date date\". " + + "Consider to declare/implement a mapping method: \"Date map(Source.MyType value)\"."), @Diagnostic(type = ErroneousJavaInternalMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \".*MyType calendar\" to \"java\\.util\\.GregorianCalendar " + - "calendar\"\\. Consider to declare/implement a mapping method: \"java\\.util\\.GregorianCalendar " + - "map\\(.*MyType value\\)\"\\."), + line = 16, + message = "Can't map property \"Source.MyType calendar\" to \"GregorianCalendar calendar\". " + + "Consider to declare/implement a mapping method: \"GregorianCalendar map(Source.MyType value)\"."), @Diagnostic(type = ErroneousJavaInternalMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \".*List<.*MyType> types\" to \".*List<.*String> types\"\\" + - ". Consider to declare/implement a mapping method: \".*List<.*String> map\\(.*List<.*MyType> " + - "value\\)\"\\."), + line = 16, + message = "Can't map property \"List types\" to \"List types\". " + + "Consider to declare/implement a mapping method: \"List map(List value)\"."), @Diagnostic(type = ErroneousJavaInternalMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 29, - messageRegExp = "Can't map property \".*List<.*MyType> nestedMyType\\.deepNestedType\\.types\" to \"" + - ".*List<.*String> nestedMyType\\.deepNestedType\\.types\"\\. Consider to declare/implement a " + - "mapping method: \".*List<.*String> map\\(.*List<.*MyType> value\\)\"\\.") + line = 16, + message = "Can't map property \"List nestedMyType.deepNestedType.types\" to " + + "\"List nestedMyType.deepNestedType.types\". " + + "Consider to declare/implement a mapping method: " + + "\"List map(List value)\".") }) - @Test - public void shouldNotNestIntoJavaPackageObjects() throws Exception { + @ProcessorTest + public void shouldNotNestIntoJavaPackageObjects() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Source.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Source.java index adeaba1266..3d29ff35ec 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Target.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Target.java index 3691541eda..63deed8b4b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/CustomMappingExclusionProvider.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/CustomMappingExclusionProvider.java index ad3461ff58..5c344c714f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/CustomMappingExclusionProvider.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/CustomMappingExclusionProvider.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions.custom; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionMapper.java index 51497f05bb..a09ce4da3e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions.custom; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionTest.java index 3196bef2e9..4fb90cf6ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/ErroneousCustomExclusionTest.java @@ -1,32 +1,17 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions.custom; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithServiceImplementation; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @author Filip Hrisafov @@ -37,7 +22,6 @@ ErroneousCustomExclusionMapper.class }) @WithServiceImplementation( CustomMappingExclusionProvider.class ) -@RunWith(AnnotationProcessorTestRunner.class) @IssueKey("1154") public class ErroneousCustomExclusionTest { @@ -45,13 +29,12 @@ public class ErroneousCustomExclusionTest { diagnostics = { @Diagnostic(type = ErroneousCustomExclusionMapper.class, kind = javax.tools.Diagnostic.Kind.ERROR, - line = 30, - messageRegExp = "Can't map property \".*NestedSource nested\" to \".*NestedTarget nested\"\\. " + - "Consider to declare/implement a mapping method: \".*NestedTarget map\\(.*NestedSource value\\)" + - "\"\\.") + line = 17, + message = "Can't map property \"Source.NestedSource nested\" to \"Target.NestedTarget nested\". " + + "Consider to declare/implement a mapping method: \"Target.NestedTarget map(Source.NestedSource value)\".") } ) - @Test + @ProcessorTest public void shouldFailToCreateMappingForExcludedClass() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Source.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Source.java index 969334da42..cf5581c726 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions.custom; @@ -52,4 +39,4 @@ public void setNested(NestedSource nested) { } // tag::documentation[] } -// tag::documentation[] +// end::documentation[] diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Target.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Target.java index e6d4b1ef22..16910601f5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/exclusions/custom/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.exclusions.custom; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionary.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionary.java index 78a27df9ee..e0fa0df8da 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionary.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionary.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.maps; import java.util.Map; +import java.util.Objects; public class AntonymsDictionary { private Map antonyms; @@ -49,7 +37,7 @@ public boolean equals(Object o) { AntonymsDictionary antonymsDictionary = (AntonymsDictionary) o; - return antonyms != null ? antonyms.equals( antonymsDictionary.antonyms ) : antonymsDictionary.antonyms == null; + return Objects.equals( antonyms, antonymsDictionary.antonyms ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionaryDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionaryDto.java index 89df76bc7a..9ac7913c9f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionaryDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AntonymsDictionaryDto.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.maps; import java.util.Map; +import java.util.Objects; public class AntonymsDictionaryDto { private Map antonyms; @@ -49,8 +37,7 @@ public boolean equals(Object o) { AntonymsDictionaryDto antonymsDictionaryDto = (AntonymsDictionaryDto) o; - return antonyms != null ? antonyms.equals( antonymsDictionaryDto.antonyms ) : - antonymsDictionaryDto.antonyms == null; + return Objects.equals( antonyms, antonymsDictionaryDto.antonyms ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AutoMapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AutoMapMapper.java index e1f2a33c2c..2184589a01 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AutoMapMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/AutoMapMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.maps; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/Word.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/Word.java index f503700f63..cd4b03114e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/Word.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/Word.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.maps; +import java.util.Objects; + public class Word { private String textValue; @@ -47,7 +36,7 @@ public boolean equals(Object o) { Word word = (Word) o; - return textValue != null ? textValue.equals( word.textValue ) : word.textValue == null; + return Objects.equals( textValue, word.textValue ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/WordDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/WordDto.java index a74eef2136..d31f025d5d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/WordDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/maps/WordDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.maps; +import java.util.Objects; + public class WordDto { private String textValue; @@ -47,7 +36,7 @@ public boolean equals(Object o) { WordDto wordDto = (WordDto) o; - return textValue != null ? textValue.equals( wordDto.textValue ) : wordDto.textValue == null; + return Objects.equals( textValue, wordDto.textValue ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/AutomappingAndNestedTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/AutomappingAndNestedTest.java index 11522e05f4..80922ae5c6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/AutomappingAndNestedTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/AutomappingAndNestedTest.java @@ -1,28 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.nestedbeans.mixed._target.FishDto; import org.mapstruct.ap.test.nestedbeans.mixed._target.FishTankDto; import org.mapstruct.ap.test.nestedbeans.mixed._target.FishTankWithNestedDocumentDto; @@ -43,10 +26,12 @@ import org.mapstruct.ap.test.nestedbeans.mixed.source.WaterQuality; import org.mapstruct.ap.test.nestedbeans.mixed.source.WaterQualityReport; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * * @author Sjaak Derksen @@ -77,18 +62,17 @@ FishTankMapperWithDocument.class }) @IssueKey("1057") -@RunWith(AnnotationProcessorTestRunner.class) public class AutomappingAndNestedTest { - @Rule - public GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( FishTankMapper.class, FishTankMapperConstant.class, FishTankMapperExpression.class, FishTankMapperWithDocument.class ); - @Test + @ProcessorTest public void shouldAutomapAndHandleSourceAndTargetPropertyNesting() { // -- prepare @@ -130,7 +114,7 @@ public void shouldAutomapAndHandleSourceAndTargetPropertyNesting() { .isEqualTo( source.getQuality().getReport().getOrganisationName() ); } - @Test + @ProcessorTest public void shouldAutomapAndHandleSourceAndTargetPropertyNestingReverse() { // -- prepare @@ -169,7 +153,7 @@ public void shouldAutomapAndHandleSourceAndTargetPropertyNestingReverse() { .isEqualTo( source.getQuality().getReport().getVerdict() ); } - @Test + @ProcessorTest public void shouldAutomapAndHandleSourceAndTargetPropertyNestingAndConstant() { // -- prepare @@ -198,7 +182,7 @@ public void shouldAutomapAndHandleSourceAndTargetPropertyNestingAndConstant() { } - @Test + @ProcessorTest public void shouldAutomapAndHandleSourceAndTargetPropertyNestingAndExpresion() { // -- prepare @@ -223,7 +207,7 @@ public void shouldAutomapAndHandleSourceAndTargetPropertyNestingAndExpresion() { assertThat( target.getQuality().getReport().getOrganisation().getName() ).isEqualTo( "Dunno" ); } - @Test + @ProcessorTest public void shouldAutomapIntermediateLevelAndMapConstant() { // -- prepare diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapper.java index ab806c0999..a730eaa541 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperConstant.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperConstant.java index 955d7e7043..1d1145b82f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperConstant.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperConstant.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperExpression.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperExpression.java index b76abb957f..02011d8799 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperExpression.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperExpression.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperWithDocument.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperWithDocument.java index d5571afea5..beeb233cd9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperWithDocument.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/FishTankMapperWithDocument.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishDto.java index a7fffe1ec5..6da67eeef1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankDto.java index 04693823c7..f3338f49a1 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankWithNestedDocumentDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankWithNestedDocumentDto.java index 0fddf165b6..7e107908f9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankWithNestedDocumentDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/FishTankWithNestedDocumentDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialDto.java index 8932b88595..19f9cb2a94 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialTypeDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialTypeDto.java index a9d46ff27d..4e5166214d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialTypeDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/MaterialTypeDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/OrnamentDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/OrnamentDto.java index 6c8153873f..f5523470f9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/OrnamentDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/OrnamentDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterPlantDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterPlantDto.java index e527e6ec7e..56e9af5e08 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterPlantDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterPlantDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityDto.java index 84f7dc229f..c4eb78d6ed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityOrganisationDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityOrganisationDto.java index e8833d35de..16c5811621 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityOrganisationDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityOrganisationDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityReportDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityReportDto.java index d5456a3090..56a107775c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityReportDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityReportDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityWithDocumentDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityWithDocumentDto.java index 35c86b243c..8fab7dc5d2 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityWithDocumentDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/_target/WaterQualityWithDocumentDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Fish.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Fish.java index 51250f42a0..3d6032be3c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Fish.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Fish.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/FishTank.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/FishTank.java index 2cfc48bb97..218df4aa57 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/FishTank.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/FishTank.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Interior.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Interior.java index ae84726637..4b5971b6c9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Interior.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Interior.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/MaterialType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/MaterialType.java index 8f83fdb16d..f81b226276 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/MaterialType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/MaterialType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Ornament.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Ornament.java index 80cc128f3c..ded7fac05f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Ornament.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/Ornament.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterPlant.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterPlant.java index 52799646c5..d083634591 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterPlant.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterPlant.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQuality.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQuality.java index 77a0e454e6..4262cf8167 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQuality.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQuality.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQualityReport.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQualityReport.java index 76dbd7cbfc..4ee0fc65f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQualityReport.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/mixed/source/WaterQualityReport.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.mixed.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/Garage.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/Garage.java index f40fdae5cb..7505aeee13 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/Garage.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/Garage.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.multiplecollections; import java.util.List; +import java.util.Objects; import org.mapstruct.ap.test.nestedbeans.Car; @@ -61,10 +49,10 @@ public boolean equals(Object o) { Garage garage = (Garage) o; - if ( cars != null ? !cars.equals( garage.cars ) : garage.cars != null ) { + if ( !Objects.equals( cars, garage.cars ) ) { return false; } - return usedCars != null ? usedCars.equals( garage.usedCars ) : garage.usedCars == null; + return Objects.equals( usedCars, garage.usedCars ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/GarageDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/GarageDto.java index f66d9f46e9..970c558f64 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/GarageDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/GarageDto.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.multiplecollections; import java.util.List; +import java.util.Objects; import org.mapstruct.ap.test.nestedbeans.CarDto; @@ -62,10 +50,10 @@ public boolean equals(Object o) { GarageDto garageDto = (GarageDto) o; - if ( cars != null ? !cars.equals( garageDto.cars ) : garageDto.cars != null ) { + if ( !Objects.equals( cars, garageDto.cars ) ) { return false; } - return usedCars != null ? usedCars.equals( garageDto.usedCars ) : garageDto.usedCars == null; + return Objects.equals( usedCars, garageDto.usedCars ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/MultipleListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/MultipleListMapper.java index e7c9dba4fe..84e7bd6414 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/MultipleListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/multiplecollections/MultipleListMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.multiplecollections; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java index 40678c5f96..a7b27970ce 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/CarDto.java @@ -1,24 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.other; import java.util.List; +import java.util.Objects; public class CarDto { @@ -73,10 +61,10 @@ public boolean equals(Object o) { if ( year != carDto.year ) { return false; } - if ( name != null ? !name.equals( carDto.name ) : carDto.name != null ) { + if ( !Objects.equals( name, carDto.name ) ) { return false; } - return wheels != null ? wheels.equals( carDto.wheels ) : carDto.wheels == null; + return Objects.equals( wheels, carDto.wheels ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java index fd927131af..d7b0631f41 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/HouseDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.other; +import java.util.Objects; + public class HouseDto { private String name; @@ -71,10 +60,10 @@ public boolean equals(Object o) { if ( year != houseDto.year ) { return false; } - if ( name != null ? !name.equals( houseDto.name ) : houseDto.name != null ) { + if ( !Objects.equals( name, houseDto.name ) ) { return false; } - return roof != null ? roof.equals( houseDto.roof ) : houseDto.roof == null; + return Objects.equals( roof, houseDto.roof ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java index 1101df7c82..05b984b89d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/RoofDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.other; +import java.util.Objects; + public class RoofDto { private String color; @@ -47,7 +36,7 @@ public boolean equals(Object o) { RoofDto roofDto = (RoofDto) o; - return color != null ? color.equals( roofDto.color ) : roofDto.color == null; + return Objects.equals( color, roofDto.color ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java index 3ede3acbaa..eb4529a212 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/UserDto.java @@ -1,23 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.other; +import java.util.Objects; + public class UserDto { private String name; @@ -68,13 +57,13 @@ public boolean equals(Object o) { UserDto userDto = (UserDto) o; - if ( name != null ? !name.equals( userDto.name ) : userDto.name != null ) { + if ( !Objects.equals( name, userDto.name ) ) { return false; } - if ( car != null ? !car.equals( userDto.car ) : userDto.car != null ) { + if ( !Objects.equals( car, userDto.car ) ) { return false; } - return house != null ? house.equals( userDto.house ) : userDto.house == null; + return Objects.equals( house, userDto.house ); } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java index feb4de4eac..0b42cc4123 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/other/WheelDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.other; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/RecursionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/RecursionMapper.java index 1ab1fe0f46..5f6cbf53d4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/RecursionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/RecursionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.recursive; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/TreeRecursionMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/TreeRecursionMapper.java index 6914fd0e36..17c647e39f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/TreeRecursionMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/recursive/TreeRecursionMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.recursive; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseCollectionElementPropertyMapper.java index 142a28ac15..193eba415e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseCollectionElementPropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseCollectionElementPropertyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepListMapper.java index 096c96c165..e37250890d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepListMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapKeyMapper.java index 0bddbb41b9..dc862ec3fd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapKeyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapKeyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapValueMapper.java index bdf2c79c9d..0bd19d06ab 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapValueMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepMapValueMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepNestingMapper.java index bb461612ae..7ce151a30a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepNestingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseDeepNestingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseValuePropertyMapper.java index e78fa0a0f2..c6b2d529c5 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseValuePropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/BaseValuePropertyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Car.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Car.java index d1ce244bbf..b69ffd46de 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CarDto.java index a4b118b849..bcff46314b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Cat.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Cat.java index 17bd0533a8..b880717dea 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Cat.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Cat.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CatDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CatDto.java index 2c80ed1a9b..8eb016705f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CatDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/CatDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Color.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Color.java index 75ecd4dc11..0e01f1285f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Color.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Color.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ColorDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ColorDto.java index 64f28c0d24..09f6cb64d3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ColorDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ColorDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Computer.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Computer.java index 8985bade34..873e3be348 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Computer.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Computer.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ComputerDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ComputerDto.java index c48e47c836..30537f1168 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ComputerDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ComputerDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Dictionary.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Dictionary.java index 1ef1e59456..b13b12e19f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Dictionary.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Dictionary.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/DictionaryDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/DictionaryDto.java index 7874537183..04cbcbb958 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/DictionaryDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/DictionaryDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ExternalRoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ExternalRoofType.java index 61e42d9ca8..01788a1c33 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ExternalRoofType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ExternalRoofType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWord.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWord.java index 436fd65b41..a0fb7b1c81 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWord.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWord.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWordDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWordDto.java index 0c22988694..165089b619 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWordDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ForeignWordDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/House.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/House.java index 05f58a9b85..d14ac4e616 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/House.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/House.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/HouseDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/HouseDto.java index 76623d419b..cbe011b2c3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/HouseDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/HouseDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Info.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Info.java index d78d41b9fa..b7c03e9dff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Info.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Info.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/InfoDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/InfoDto.java index e8e1c0ba02..1d816efde4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/InfoDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/InfoDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Roof.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Roof.java index 8670355d6a..15592d174a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Roof.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Roof.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofDto.java index 8a4ac2837d..cfa2229b15 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofType.java index 69c75e7b5b..b7271b6d96 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofTypeMapper.java index 97af82875b..28d245efc9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofTypeMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/RoofTypeMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/User.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/User.java index a183cbfef2..3f0009a5dc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/User.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/User.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/UserDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/UserDto.java index 7c6977fe7c..427b0dd8b8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/UserDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/UserDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Wheel.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Wheel.java index d704d5d102..b8f836441b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Wheel.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Wheel.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WheelDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WheelDto.java index 60aa9620f0..b26d7951be 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WheelDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WheelDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Word.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Word.java index 97e4288da0..d2fb22fd4b 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Word.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/Word.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WordDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WordDto.java index 1a0c439ff2..e532753ce3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WordDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/WordDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableCollectionElementPropertyMapper.java deleted file mode 100644 index 8c29fc2968..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableCollectionElementPropertyMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR) -public abstract class UnmappableCollectionElementPropertyMapper extends BaseCollectionElementPropertyMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepListMapper.java deleted file mode 100644 index b62360a62d..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepListMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR) -public abstract class UnmappableDeepListMapper extends BaseDeepListMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepMapKeyMapper.java deleted file mode 100644 index 7c5cf9a00e..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepMapKeyMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR) -public abstract class UnmappableDeepMapKeyMapper extends BaseDeepMapKeyMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepMapValueMapper.java deleted file mode 100644 index 8d73d33563..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepMapValueMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR) -public abstract class UnmappableDeepMapValueMapper extends BaseDeepMapValueMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepNestingMapper.java deleted file mode 100644 index bd9b8f0ed2..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableDeepNestingMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR) -public abstract class UnmappableDeepNestingMapper extends BaseDeepNestingMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableEnumMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableEnumMapper.java deleted file mode 100644 index 86a1753e47..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableEnumMapper.java +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.Car; -import org.mapstruct.ap.test.nestedbeans.unmappable.CarDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Cat; -import org.mapstruct.ap.test.nestedbeans.unmappable.CatDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Color; -import org.mapstruct.ap.test.nestedbeans.unmappable.ColorDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Computer; -import org.mapstruct.ap.test.nestedbeans.unmappable.ComputerDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.Dictionary; -import org.mapstruct.ap.test.nestedbeans.unmappable.DictionaryDto; -import org.mapstruct.ap.test.nestedbeans.unmappable.User; -import org.mapstruct.ap.test.nestedbeans.unmappable.UserDto; - -@Mapper -public abstract class UnmappableEnumMapper { - - abstract UserDto userToUserDto(User user); - - public ColorDto map(Color color) { - return new ColorDto(); - } - - public CarDto map(Car carDto) { - return new CarDto(); - } - - public DictionaryDto map(Dictionary dictionary) { - return new DictionaryDto(); - } - - public ComputerDto map(Computer computer) { - return new ComputerDto(); - } - - public CatDto map(Cat cat) { - return new CatDto(); - } -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceCollectionElementPropertyMapper.java new file mode 100644 index 0000000000..28265073ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceCollectionElementPropertyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.ERROR; +import static org.mapstruct.ReportingPolicy.IGNORE; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = ERROR ) +public abstract class UnmappableSourceCollectionElementPropertyMapper extends BaseCollectionElementPropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepListMapper.java new file mode 100644 index 0000000000..7d4b89f4aa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepListMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.ERROR; +import static org.mapstruct.ReportingPolicy.IGNORE; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = ERROR ) +public abstract class UnmappableSourceDeepListMapper extends BaseDeepListMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepMapKeyMapper.java new file mode 100644 index 0000000000..01a3e48de6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepMapKeyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.ERROR; +import static org.mapstruct.ReportingPolicy.IGNORE; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = ERROR ) +public abstract class UnmappableSourceDeepMapKeyMapper extends BaseDeepMapKeyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepMapValueMapper.java new file mode 100644 index 0000000000..ba606a6222 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepMapValueMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.ERROR; +import static org.mapstruct.ReportingPolicy.IGNORE; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = ERROR ) +public abstract class UnmappableSourceDeepMapValueMapper extends BaseDeepMapValueMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepNestingMapper.java new file mode 100644 index 0000000000..1ec7dbd36c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceDeepNestingMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.ERROR; +import static org.mapstruct.ReportingPolicy.IGNORE; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = ERROR ) +public abstract class UnmappableSourceDeepNestingMapper extends BaseDeepNestingMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceEnumMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceEnumMapper.java new file mode 100644 index 0000000000..8fcb737ee4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceEnumMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.Car; +import org.mapstruct.ap.test.nestedbeans.unmappable.CarDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Cat; +import org.mapstruct.ap.test.nestedbeans.unmappable.CatDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Color; +import org.mapstruct.ap.test.nestedbeans.unmappable.ColorDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Computer; +import org.mapstruct.ap.test.nestedbeans.unmappable.ComputerDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.Dictionary; +import org.mapstruct.ap.test.nestedbeans.unmappable.DictionaryDto; +import org.mapstruct.ap.test.nestedbeans.unmappable.User; +import org.mapstruct.ap.test.nestedbeans.unmappable.UserDto; + +@Mapper +public abstract class UnmappableSourceEnumMapper { + + abstract UserDto userToUserDto(User user); + + public ColorDto map(Color color) { + return new ColorDto(); + } + + public CarDto map(Car carDto) { + return new CarDto(); + } + + public DictionaryDto map(Dictionary dictionary) { + return new DictionaryDto(); + } + + public ComputerDto map(Computer computer) { + return new ComputerDto(); + } + + public CatDto map(Cat cat) { + return new CatDto(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceValuePropertyMapper.java new file mode 100644 index 0000000000..4b686642c3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableSourceValuePropertyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.ERROR; +import static org.mapstruct.ReportingPolicy.IGNORE; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = ERROR ) +public abstract class UnmappableSourceValuePropertyMapper extends BaseValuePropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetCollectionElementPropertyMapper.java new file mode 100644 index 0000000000..5198324cbe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetCollectionElementPropertyMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR ) +public abstract class UnmappableTargetCollectionElementPropertyMapper extends BaseCollectionElementPropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepListMapper.java new file mode 100644 index 0000000000..993e30ec60 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepListMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR ) +public abstract class UnmappableTargetDeepListMapper extends BaseDeepListMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepMapKeyMapper.java new file mode 100644 index 0000000000..e30533d00d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepMapKeyMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR ) +public abstract class UnmappableTargetDeepMapKeyMapper extends BaseDeepMapKeyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepMapValueMapper.java new file mode 100644 index 0000000000..f46651dbc1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepMapValueMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR ) +public abstract class UnmappableTargetDeepMapValueMapper extends BaseDeepMapValueMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepNestingMapper.java new file mode 100644 index 0000000000..736aef3d84 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetDeepNestingMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR ) +public abstract class UnmappableTargetDeepNestingMapper extends BaseDeepNestingMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetValuePropertyMapper.java new file mode 100644 index 0000000000..e43f7d2e1a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableTargetValuePropertyMapper.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; + +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR ) +public abstract class UnmappableTargetValuePropertyMapper extends BaseValuePropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableValuePropertyMapper.java deleted file mode 100644 index 57d2fe510d..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/erroneous/UnmappableValuePropertyMapper.java +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.erroneous; - -import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class, unmappedTargetPolicy = ReportingPolicy.ERROR) -public abstract class UnmappableValuePropertyMapper extends BaseValuePropertyMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreCollectionElementPropertyMapper.java index 3d7b19401d..06311e41dd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreCollectionElementPropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreCollectionElementPropertyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepListMapper.java index 746777bc25..df80002650 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepListMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepListMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapKeyMapper.java index 8dc34f372b..51d2366afc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapKeyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapKeyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapValueMapper.java index 5255246fe6..a8566def9e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapValueMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepMapValueMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepNestingMapper.java index 4ba701427e..eb4b374cde 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepNestingMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreDeepNestingMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreValuePropertyMapper.java index 000c0a271a..5b51ac7499 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreValuePropertyMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/ignore/UnmappableIgnoreValuePropertyMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedbeans.unmappable.ignore; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnCollectionElementPropertyMapper.java new file mode 100644 index 0000000000..500b1d7a37 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnCollectionElementPropertyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = WARN ) +public abstract class UnmappableSourceWarnCollectionElementPropertyMapper extends BaseCollectionElementPropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepListMapper.java new file mode 100644 index 0000000000..dafe6836a6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepListMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = WARN ) +public abstract class UnmappableSourceWarnDeepListMapper extends BaseDeepListMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepMapKeyMapper.java new file mode 100644 index 0000000000..8191ced79c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepMapKeyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = WARN ) +public abstract class UnmappableSourceWarnDeepMapKeyMapper extends BaseDeepMapKeyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepMapValueMapper.java new file mode 100644 index 0000000000..4152c22c30 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepMapValueMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = WARN ) +public abstract class UnmappableSourceWarnDeepMapValueMapper extends BaseDeepMapValueMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepNestingMapper.java new file mode 100644 index 0000000000..86631e25bf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnDeepNestingMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = WARN ) +public abstract class UnmappableSourceWarnDeepNestingMapper extends BaseDeepNestingMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnValuePropertyMapper.java new file mode 100644 index 0000000000..90473cac6d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableSourceWarnValuePropertyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = IGNORE, unmappedSourcePolicy = WARN ) +public abstract class UnmappableSourceWarnValuePropertyMapper extends BaseValuePropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnCollectionElementPropertyMapper.java new file mode 100644 index 0000000000..4992ffbd69 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnCollectionElementPropertyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = WARN, unmappedSourcePolicy = IGNORE ) +public abstract class UnmappableTargetWarnCollectionElementPropertyMapper extends BaseCollectionElementPropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepListMapper.java new file mode 100644 index 0000000000..36bab5a93c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepListMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = WARN, unmappedSourcePolicy = IGNORE ) +public abstract class UnmappableTargetWarnDeepListMapper extends BaseDeepListMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepMapKeyMapper.java new file mode 100644 index 0000000000..452574c5e5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepMapKeyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = WARN, unmappedSourcePolicy = IGNORE ) +public abstract class UnmappableTargetWarnDeepMapKeyMapper extends BaseDeepMapKeyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepMapValueMapper.java new file mode 100644 index 0000000000..ebcca95b6d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepMapValueMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = WARN, unmappedSourcePolicy = IGNORE ) +public abstract class UnmappableTargetWarnDeepMapValueMapper extends BaseDeepMapValueMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepNestingMapper.java new file mode 100644 index 0000000000..466947b2a3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnDeepNestingMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = WARN, unmappedSourcePolicy = IGNORE ) +public abstract class UnmappableTargetWarnDeepNestingMapper extends BaseDeepNestingMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnValuePropertyMapper.java new file mode 100644 index 0000000000..1af841048f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableTargetWarnValuePropertyMapper.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nestedbeans.unmappable.warn; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; +import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; + +import static org.mapstruct.ReportingPolicy.IGNORE; +import static org.mapstruct.ReportingPolicy.WARN; + +@Mapper( uses = RoofTypeMapper.class, unmappedTargetPolicy = WARN, unmappedSourcePolicy = IGNORE ) +public abstract class UnmappableTargetWarnValuePropertyMapper extends BaseValuePropertyMapper { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnCollectionElementPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnCollectionElementPropertyMapper.java deleted file mode 100644 index 69ad7272fc..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnCollectionElementPropertyMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.warn; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseCollectionElementPropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class) -public abstract class UnmappableWarnCollectionElementPropertyMapper extends BaseCollectionElementPropertyMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepListMapper.java deleted file mode 100644 index 429aee3b37..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepListMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.warn; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepListMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class) -public abstract class UnmappableWarnDeepListMapper extends BaseDeepListMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepMapKeyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepMapKeyMapper.java deleted file mode 100644 index b98f994d6e..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepMapKeyMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.warn; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapKeyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class) -public abstract class UnmappableWarnDeepMapKeyMapper extends BaseDeepMapKeyMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepMapValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepMapValueMapper.java deleted file mode 100644 index f594336ef2..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepMapValueMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.warn; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepMapValueMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class) -public abstract class UnmappableWarnDeepMapValueMapper extends BaseDeepMapValueMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepNestingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepNestingMapper.java deleted file mode 100644 index cc71221f08..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnDeepNestingMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.warn; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseDeepNestingMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class) -public abstract class UnmappableWarnDeepNestingMapper extends BaseDeepNestingMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnValuePropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnValuePropertyMapper.java deleted file mode 100644 index 42a79040a1..0000000000 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedbeans/unmappable/warn/UnmappableWarnValuePropertyMapper.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.mapstruct.ap.test.nestedbeans.unmappable.warn; - -import org.mapstruct.Mapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.BaseValuePropertyMapper; -import org.mapstruct.ap.test.nestedbeans.unmappable.RoofTypeMapper; - -@Mapper(uses = RoofTypeMapper.class) -public abstract class UnmappableWarnValuePropertyMapper extends BaseValuePropertyMapper { -} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/NestedMappingMethodInvocationTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/NestedMappingMethodInvocationTest.java index 93ba0a6f74..03c47f7a49 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/NestedMappingMethodInvocationTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/NestedMappingMethodInvocationTest.java @@ -1,30 +1,14 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.ArrayList; +import java.util.Calendar; import java.util.GregorianCalendar; import java.util.List; -import java.util.Locale; - import javax.xml.bind.JAXBElement; import javax.xml.datatype.DatatypeConfigurationException; import javax.xml.datatype.DatatypeConstants; @@ -32,12 +16,14 @@ import javax.xml.datatype.XMLGregorianCalendar; import javax.xml.namespace.QName; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junitpioneer.jupiter.DefaultLocale; +import org.junitpioneer.jupiter.ReadsDefaultTimeZone; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; +import org.mapstruct.ap.testutil.WithJavaxJaxb; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for the nested invocation of mapping methods. @@ -45,17 +31,13 @@ * @author Sjaak Derksen */ @IssueKey("134") -@RunWith(AnnotationProcessorTestRunner.class) +@DefaultLocale("de") +@ReadsDefaultTimeZone public class NestedMappingMethodInvocationTest { public static final QName QNAME = new QName( "dont-care" ); - @Before - public void setDefaultLocale() { - Locale.setDefault( Locale.GERMAN ); - } - - @Test + @ProcessorTest @WithClasses( { OrderTypeToOrderDtoMapper.class, OrderDto.class, @@ -63,6 +45,7 @@ public void setDefaultLocale() { OrderDetailsType.class, OrderType.class } ) + @WithJavaxJaxb public void shouldMapViaMethodAndMethod() throws DatatypeConfigurationException { OrderTypeToOrderDtoMapper instance = OrderTypeToOrderDtoMapper.INSTANCE; OrderDto target = instance.sourceToTarget( createOrderType() ); @@ -76,30 +59,32 @@ public void shouldMapViaMethodAndMethod() throws DatatypeConfigurationException assertThat( target.getOrderDetails().getDescription() ).containsExactly( "elem1", "elem2" ); } - @Test + @ProcessorTest @WithClasses( { SourceTypeTargetDtoMapper.class, SourceType.class, ObjectFactory.class, TargetDto.class } ) - public void shouldMapViaMethodAndConversion() throws DatatypeConfigurationException { + @WithJavaxJaxb + public void shouldMapViaMethodAndConversion() { SourceTypeTargetDtoMapper instance = SourceTypeTargetDtoMapper.INSTANCE; TargetDto target = instance.sourceToTarget( createSource() ); assertThat( target ).isNotNull(); - assertThat( target.getDate() ).isEqualTo( new GregorianCalendar( 2013, 6, 6 ).getTime() ); + assertThat( target.getDate() ).isEqualTo( new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime() ); } - @Test + @ProcessorTest @WithClasses( { SourceTypeTargetDtoMapper.class, SourceType.class, ObjectFactory.class, TargetDto.class } ) - public void shouldMapViaConversionAndMethod() throws DatatypeConfigurationException { + @WithJavaxJaxb + public void shouldMapViaConversionAndMethod() { SourceTypeTargetDtoMapper instance = SourceTypeTargetDtoMapper.INSTANCE; SourceType source = instance.targetToSource( createTarget() ); @@ -110,36 +95,36 @@ public void shouldMapViaConversionAndMethod() throws DatatypeConfigurationExcept } private OrderType createOrderType() throws DatatypeConfigurationException { - List> dates = new ArrayList>(); + List> dates = new ArrayList<>(); dates.add( - new JAXBElement( - QNAME, - XMLGregorianCalendar.class, - createXmlCal( 1999, 3, 2 ) - ) + new JAXBElement<>( + QNAME, + XMLGregorianCalendar.class, + createXmlCal( 1999, 3, 2 ) + ) ); dates.add( - new JAXBElement( - QNAME, - XMLGregorianCalendar.class, - createXmlCal( 2004, 7, 28 ) - ) + new JAXBElement<>( + QNAME, + XMLGregorianCalendar.class, + createXmlCal( 2004, 7, 28 ) + ) ); - List> description = new ArrayList>(); - description.add( new JAXBElement( QNAME, String.class, "elem1" ) ); - description.add( new JAXBElement( QNAME, String.class, "elem2" ) ); + List> description = new ArrayList<>(); + description.add( new JAXBElement<>( QNAME, String.class, "elem1" ) ); + description.add( new JAXBElement<>( QNAME, String.class, "elem2" ) ); OrderType orderType = new OrderType(); - orderType.setOrderNumber( new JAXBElement( QNAME, Long.class, 5L ) ); + orderType.setOrderNumber( new JAXBElement<>( QNAME, Long.class, 5L ) ); orderType.setOrderDetails( - new JAXBElement( - QNAME, - OrderDetailsType.class, - new OrderDetailsType() - ) + new JAXBElement<>( + QNAME, + OrderDetailsType.class, + new OrderDetailsType() + ) ); - orderType.getOrderDetails().getValue().setName( new JAXBElement( QNAME, String.class, "test" ) ); + orderType.getOrderDetails().getValue().setName( new JAXBElement<>( QNAME, String.class, "test" ) ); orderType.getOrderDetails().getValue().setDescription( description ); orderType.setDates( dates ); @@ -154,13 +139,13 @@ private XMLGregorianCalendar createXmlCal( int year, int month, int day ) private SourceType createSource() { SourceType source = new SourceType(); - source.setDate( new JAXBElement( QNAME, String.class, "06.07.2013" ) ); + source.setDate( new JAXBElement<>( QNAME, String.class, "06.07.2013" ) ); return source; } private TargetDto createTarget() { TargetDto target = new TargetDto(); - target.setDate( new GregorianCalendar( 2013, 6, 6 ).getTime() ); + target.setDate( new GregorianCalendar( 2013, Calendar.JULY, 6 ).getTime() ); return target; } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/ObjectFactory.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/ObjectFactory.java index 8d06287e3f..3d2c454255 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/ObjectFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/ObjectFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; @@ -28,6 +15,6 @@ public class ObjectFactory { public JAXBElement createDate(String date) { - return new JAXBElement( new QName( "dont-care" ), String.class, "06.07.2013" ); + return new JAXBElement<>( new QName( "dont-care" ), String.class, "06.07.2013" ); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsDto.java index 961cbe3a8a..4ad888b8bb 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsType.java index fab5b13543..98547b38ff 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDetailsType.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; import java.util.List; - import javax.xml.bind.JAXBElement; /** diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDto.java index 2ada9268fc..8a4d63fc0f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderType.java index e28417f401..6fdef2705e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderType.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; import java.util.List; - import javax.xml.bind.JAXBElement; import javax.xml.datatype.XMLGregorianCalendar; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderTypeToOrderDtoMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderTypeToOrderDtoMapper.java index cda6faf010..24ea469135 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderTypeToOrderDtoMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/OrderTypeToOrderDtoMapper.java @@ -1,25 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; import java.util.List; - import javax.xml.bind.JAXBElement; import javax.xml.datatype.XMLGregorianCalendar; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceType.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceType.java index 457819d919..cdf69bd156 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceType.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceType.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceTypeTargetDtoMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceTypeTargetDtoMapper.java index aa1f0827bf..895d3dc922 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceTypeTargetDtoMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/SourceTypeTargetDtoMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; @@ -30,7 +17,7 @@ public interface SourceTypeTargetDtoMapper { SourceTypeTargetDtoMapper INSTANCE = Mappers.getMapper( SourceTypeTargetDtoMapper.class ); - @Mapping(source = "date", target = "date", dateFormat = "dd.MM.yyyy") + @Mapping(target = "date", source = "date", dateFormat = "dd.MM.yyyy") TargetDto sourceToTarget(SourceType source); SourceType targetToSource( TargetDto source ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/TargetDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/TargetDto.java index 826d136110..636c44967a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/TargetDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedmethodcall/TargetDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedmethodcall; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleMapper.java index e0a2f19dc8..0639399434 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedproperties.simple; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleNestedPropertiesTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleNestedPropertiesTest.java index de9aa7e9e5..ae5833794e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleNestedPropertiesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/SimpleNestedPropertiesTest.java @@ -1,55 +1,40 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedproperties.simple; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.nestedproperties.simple._target.TargetObject; import org.mapstruct.ap.test.nestedproperties.simple.source.SourceProps; import org.mapstruct.ap.test.nestedproperties.simple.source.SourceRoot; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Sebastian Hasait */ @WithClasses({ SourceRoot.class, SourceProps.class, TargetObject.class }) @IssueKey("407") -@RunWith(AnnotationProcessorTestRunner.class) public class SimpleNestedPropertiesTest { - @Test + @ProcessorTest @WithClasses({ SimpleMapper.class }) public void testNull() { TargetObject targetObject = SimpleMapper.MAPPER.toTargetObject( null ); - assertNull( targetObject ); + assertThat( targetObject ).isNull(); } - @Test + @ProcessorTest @WithClasses({ SimpleMapper.class }) public void testViaNull() { SourceRoot sourceRoot = new SourceRoot(); @@ -70,7 +55,7 @@ public void testViaNull() { assertNull( targetObject.getStringValue() ); } - @Test + @ProcessorTest @WithClasses({ SimpleMapper.class }) public void testFilled() { SourceRoot sourceRoot = new SourceRoot(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/_target/TargetObject.java b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/_target/TargetObject.java index b2936a1bbb..283faf4e71 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/_target/TargetObject.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/_target/TargetObject.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedproperties.simple._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceProps.java b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceProps.java index 05d07160c1..dabfe62616 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceProps.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceProps.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedproperties.simple.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceRoot.java b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceRoot.java index b570b326e4..5464a81795 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceRoot.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedproperties/simple/source/SourceRoot.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedproperties.simple.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Bucket.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Bucket.java index d541723c27..b9f1b6d369 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Bucket.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Bucket.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NestedExceptionTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NestedExceptionTest.java index 06b481eac2..97206784aa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NestedExceptionTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NestedExceptionTest.java @@ -1,28 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; /** * @@ -37,10 +22,9 @@ ResourceMapper.class }) @IssueKey("1332") -@RunWith(AnnotationProcessorTestRunner.class) public class NestedExceptionTest { - @Test + @ProcessorTest public void shouldGenerateCodeThatCompiles() { } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NoSuchUser.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NoSuchUser.java index 0a8044639a..f1f684d794 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NoSuchUser.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/NoSuchUser.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Resource.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Resource.java index 255e05e103..821f3e2d05 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Resource.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/Resource.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceDto.java index 00c720aa75..7eba6bb696 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceMapper.java index 0b8b706cae..712d160908 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/ResourceMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; @@ -28,7 +15,7 @@ @Mapper public interface ResourceMapper { - @Mapping(source = "bucket.user.uuid", target = "userId") + @Mapping(target = "userId", source = "bucket.user.uuid") ResourceDto map(Resource r) throws NoSuchUser; } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/User.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/User.java index 0f7724b81c..9c14fd3557 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/User.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/exceptions/User.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.exceptions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/FontDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/FontDto.java index e7f7be1855..3c48b98a1c 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/FontDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/FontDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.parameter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterDto.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterDto.java index 0f5f88f184..3d5bd4e5af 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.parameter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterEntity.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterEntity.java index b17ebc9ea9..139b9e0a3d 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterEntity.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterEntity.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.parameter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterMapper.java index 273f7208f0..6815299421 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/LetterMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.parameter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/NormalizingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/NormalizingTest.java index 0cd9258a89..de9a821527 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/NormalizingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsource/parameter/NormalizingTest.java @@ -1,40 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsource.parameter; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Sjaak Derksen */ @WithClasses({ FontDto.class, LetterDto.class, LetterEntity.class, LetterMapper.class }) @IssueKey("836") -@RunWith(AnnotationProcessorTestRunner.class) public class NormalizingTest { - @Test + @ProcessorTest public void shouldGenerateImplementationForPropertyNamesOnly() { FontDto fontIn = new FontDto(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntry.java index 5fb685d5c9..e1d1c865bc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntry.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntry.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryAdder.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryAdder.java index 4b1679886b..7d8f284446 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryAdder.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryAdder.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryComposedReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryComposedReverse.java index 673c032799..3cfaa6c0d9 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryComposedReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryComposedReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryConfig.java index c4c1c6613f..bbb1608133 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryErroneous.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryErroneous.java index c01772f1fa..5f8be28763 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryErroneous.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryErroneous.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; @@ -41,9 +28,22 @@ public interface ArtistToChartEntryErroneous { @Mapping(target = "city", ignore = true), @Mapping(target = "position", source = "position") } ) - ChartEntry forward(Integer position); + ChartEntry forward(ChartPosition position); @InheritInverseConfiguration - Integer reverse(ChartEntry position); + ChartPosition reverse(ChartEntry position); + + class ChartPosition { + + private final int position; + + private ChartPosition(int position) { + this.position = position; + } + + public int getPosition() { + return position; + } + } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryGetter.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryGetter.java index fce09b5f6c..6f5b5382ed 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryGetter.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryGetter.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryReverse.java index 752fcb4b46..b6ce2d786f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryUpdateReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryUpdateReverse.java index 6c977c38e3..836e6a3699 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryUpdateReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryUpdateReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithConfigReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithConfigReverse.java index bd934dc10c..8f9754777f 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithConfigReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithConfigReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithFactoryReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithFactoryReverse.java index 7bf2885867..f1862c53b7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithFactoryReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithFactoryReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithIgnoresReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithIgnoresReverse.java index a067490993..c782f3d8b3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithIgnoresReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithIgnoresReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithMappingReverse.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithMappingReverse.java index 74f5f2709b..bc8e798634 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithMappingReverse.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ArtistToChartEntryWithMappingReverse.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/NestedSourcePropertiesTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/NestedSourcePropertiesTest.java index 8edf24f685..2a0a80cbda 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/NestedSourcePropertiesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/NestedSourcePropertiesTest.java @@ -1,32 +1,13 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - import java.util.Arrays; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.nestedsourceproperties._target.AdderUsageObserver; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartPositions; @@ -36,25 +17,26 @@ import org.mapstruct.ap.test.nestedsourceproperties.source.Song; import org.mapstruct.ap.test.nestedsourceproperties.source.Studio; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; +import static org.assertj.core.api.Assertions.assertThat; + /** * @author Sjaak Derksen */ @WithClasses({ Song.class, Artist.class, Chart.class, Label.class, Studio.class, ChartEntry.class }) @IssueKey("65") -@RunWith(AnnotationProcessorTestRunner.class) public class NestedSourcePropertiesTest { - @Rule - public final GeneratedSource generatedSource = new GeneratedSource(); + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntry.class }) public void shouldGenerateImplementationForPropertyNamesOnly() { generatedSource.addComparisonToFixtureFor( ArtistToChartEntry.class ); @@ -86,7 +68,7 @@ public void shouldGenerateImplementationForPropertyNamesOnly() { assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntry.class }) public void shouldGenerateImplementationForMultipleParam() { @@ -121,7 +103,7 @@ public void shouldGenerateImplementationForMultipleParam() { assertThat( chartEntry.getSongTitle() ).isEqualTo( "A Hard Day's Night" ); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntry.class }) public void shouldPickPropertyNameOverParameterName() { @@ -140,7 +122,7 @@ public void shouldPickPropertyNameOverParameterName() { assertThat( chartEntry.getSongTitle() ).isNull(); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryAdder.class, ChartPositions.class, AdderUsageObserver.class }) public void shouldUseAddAsTargetAccessor() { @@ -155,10 +137,10 @@ public void shouldUseAddAsTargetAccessor() { assertThat( positions ).isNotNull(); assertThat( positions.getPositions() ).containsExactly( 3L, 5L ); - assertTrue( AdderUsageObserver.isUsed() ); + assertThat( AdderUsageObserver.isUsed() ).isTrue(); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryGetter.class, ChartPositions.class, AdderUsageObserver.class }) public void shouldUseGetAsTargetAccessor() { @@ -173,21 +155,21 @@ public void shouldUseGetAsTargetAccessor() { assertThat( positions ).isNotNull(); assertThat( positions.getPositions() ).containsExactly( 3L, 5L ); - assertFalse( AdderUsageObserver.isUsed() ); + assertThat( AdderUsageObserver.isUsed() ).isFalse(); } - @Test - @IssueKey( "838" ) + @ProcessorTest + @IssueKey("838") @ExpectedCompilationOutcome( - value = CompilationResult.FAILED, - diagnostics = { - @Diagnostic( type = ArtistToChartEntryErroneous.class, - kind = javax.tools.Diagnostic.Kind.ERROR, - line = 47, - messageRegExp = "java.lang.Integer does not have an accessible parameterless constructor." ) - } + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ArtistToChartEntryErroneous.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 34, + message = "ArtistToChartEntryErroneous.ChartPosition does not have an accessible constructor.") + } ) @WithClasses({ ArtistToChartEntryErroneous.class }) - public void reverseShouldRaiseErrorForEmptyContructor() { + public void inverseShouldRaiseErrorForNotAccessibleConstructor() { } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ReversingNestedSourcePropertiesTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ReversingNestedSourcePropertiesTest.java index 2b67d531ac..2010a205de 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ReversingNestedSourcePropertiesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/ReversingNestedSourcePropertiesTest.java @@ -1,28 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.nestedsourceproperties._target.BaseChartEntry; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntryComposed; @@ -36,18 +18,19 @@ import org.mapstruct.ap.test.nestedsourceproperties.source.SourceDtoFactory; import org.mapstruct.ap.test.nestedsourceproperties.source.Studio; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * @author Sjaak Derksen */ @IssueKey("389") @WithClasses({ Song.class, Artist.class, Chart.class, Label.class, Studio.class, ChartEntry.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class ReversingNestedSourcePropertiesTest { - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryReverse.class }) public void shouldGenerateNestedReverse() { @@ -76,7 +59,7 @@ public void shouldGenerateNestedReverse() { assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryWithIgnoresReverse.class }) public void shouldIgnoreEverytingBelowArtist() { @@ -99,7 +82,7 @@ public void shouldIgnoreEverytingBelowArtist() { assertThat( song2.getArtist() ).isNull(); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryUpdateReverse.class }) public void shouldGenerateNestedUpdateReverse() { @@ -129,7 +112,7 @@ public void shouldGenerateNestedUpdateReverse() { assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); } - @Test + @ProcessorTest @WithClasses( { ArtistToChartEntryWithFactoryReverse.class, SourceDtoFactory.class } ) public void shouldGenerateNestedReverseWithFactory() { @@ -164,7 +147,7 @@ public void shouldGenerateNestedReverseWithFactory() { } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryComposedReverse.class, ChartEntryComposed.class, ChartEntryLabel.class }) public void shouldGenerateNestedComposedReverse() { @@ -194,7 +177,7 @@ public void shouldGenerateNestedComposedReverse() { assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryWithMappingReverse.class, ChartEntryWithMapping.class }) public void shouldGenerateNestedWithMappingReverse() { @@ -223,7 +206,7 @@ public void shouldGenerateNestedWithMappingReverse() { assertThat( song2.getArtist().getLabel().getStudio().getName() ).isEqualTo( "Abbey Road" ); } - @Test + @ProcessorTest @WithClasses({ ArtistToChartEntryWithConfigReverse.class, ArtistToChartEntryConfig.class, diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/AdderUsageObserver.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/AdderUsageObserver.java index 0e458f10b0..e7cae29460 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/AdderUsageObserver.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/AdderUsageObserver.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/BaseChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/BaseChartEntry.java index 80c5b0f811..25376dd6fd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/BaseChartEntry.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/BaseChartEntry.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntry.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntry.java index 3015a3df35..c9bf625ef0 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntry.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntry.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryComposed.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryComposed.java index a17d969b14..45f8a4cf42 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryComposed.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryComposed.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryLabel.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryLabel.java index b881b77e21..77d2e68655 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryLabel.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryLabel.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithBase.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithBase.java index 9e39b89a4c..3c09111865 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithBase.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithBase.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithMapping.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithMapping.java index 2663411230..4873b3f9a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithMapping.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartEntryWithMapping.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartPositions.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartPositions.java index 51d6bacd3a..f91534fe99 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartPositions.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/_target/ChartPositions.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties._target; @@ -26,7 +13,7 @@ */ public class ChartPositions { - private final List positions = new ArrayList(); + private final List positions = new ArrayList<>(); public List getPositions() { return positions; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Artist.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Artist.java index 62a87eedb1..f1d6281e46 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Artist.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Artist.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Chart.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Chart.java index 778721a5b7..4fd5b86048 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Chart.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Chart.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Label.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Label.java index e3bc4bb234..23e467dc36 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Label.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Label.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Song.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Song.java index 8b5de5e9d4..f1ebe50745 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Song.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Song.java @@ -1,26 +1,12 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties.source; import java.util.List; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/SourceDtoFactory.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/SourceDtoFactory.java index 47f2874cc7..503f174820 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/SourceDtoFactory.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/SourceDtoFactory.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Studio.java b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Studio.java index 334a47276b..61adfa53aa 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Studio.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedsourceproperties/source/Studio.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedsourceproperties.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtist.java b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtist.java index 966deb68ca..db8d635d62 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtist.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtist.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedtargetproperties; @@ -65,10 +52,10 @@ public abstract class ChartEntryToArtist { protected List mapPosition(Integer in) { if ( in != null ) { - return new ArrayList( Arrays.asList( in ) ); + return new ArrayList<>( Arrays.asList( in ) ); } else { - return new ArrayList(); + return new ArrayList<>(); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java index 3d5859ffb7..eb9191daf3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/ChartEntryToArtistUpdate.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedtargetproperties; @@ -27,6 +14,7 @@ import org.mapstruct.MappingTarget; import org.mapstruct.Mappings; import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.NullValuePropertyMappingStrategy; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry; import org.mapstruct.ap.test.nestedsourceproperties.source.Chart; import org.mapstruct.factory.Mappers; @@ -34,7 +22,10 @@ /** * @author Sjaak Derksen */ -@Mapper( nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS ) +@Mapper( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE +) public abstract class ChartEntryToArtistUpdate { public static final ChartEntryToArtistUpdate MAPPER = Mappers.getMapper( ChartEntryToArtistUpdate.class ); @@ -55,7 +46,7 @@ protected List mapPosition(Integer in) { return Arrays.asList( in ); } else { - return Collections.emptyList(); + return Collections.emptyList(); } } diff --git a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/NestedProductPropertiesTest.java b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/NestedProductPropertiesTest.java index 012afbff9c..b10c51ab39 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/NestedProductPropertiesTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nestedtargetproperties/NestedProductPropertiesTest.java @@ -1,26 +1,11 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nestedtargetproperties; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; +import org.junit.jupiter.api.extension.RegisterExtension; import org.mapstruct.ap.test.nestedsourceproperties._target.ChartEntry; import org.mapstruct.ap.test.nestedsourceproperties.source.Artist; import org.mapstruct.ap.test.nestedsourceproperties.source.Chart; @@ -28,8 +13,8 @@ import org.mapstruct.ap.test.nestedsourceproperties.source.Song; import org.mapstruct.ap.test.nestedsourceproperties.source.Studio; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.GeneratedSource; import static org.assertj.core.api.Assertions.assertThat; @@ -49,16 +34,15 @@ ChartEntryToArtistUpdate.class } ) @IssueKey("389") -@RunWith(AnnotationProcessorTestRunner.class) public class NestedProductPropertiesTest { - @Rule - public GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor( ChartEntryToArtist.class, ChartEntryToArtistUpdate.class ); - @Test + @ProcessorTest public void shouldMapNestedTarget() { ChartEntry chartEntry = new ChartEntry(); @@ -87,7 +71,7 @@ public void shouldMapNestedTarget() { } - @Test + @ProcessorTest public void shouldMapNestedComposedTarget() { ChartEntry chartEntry1 = new ChartEntry(); @@ -118,7 +102,7 @@ public void shouldMapNestedComposedTarget() { } - @Test + @ProcessorTest public void shouldReverseNestedTarget() { ChartEntry chartEntry = new ChartEntry(); @@ -141,7 +125,7 @@ public void shouldReverseNestedTarget() { assertThat( result.getSongTitle() ).isEqualTo( "Purple Rain" ); } - @Test + @ProcessorTest public void shouldMapNestedTargetWitUpdate() { ChartEntry chartEntry = new ChartEntry(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/Actor.java b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/Actor.java index 8faebcc39a..ed9cdb6453 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/Actor.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/Actor.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nonvoidsetter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorDto.java b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorDto.java index d9bd21560a..e5d99c88f4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nonvoidsetter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorMapper.java index de9ba1c9c5..1b77ff849a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/ActorMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nonvoidsetter; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/NonVoidSettersTest.java b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/NonVoidSettersTest.java index 3e8a92f30e..883464ebfe 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/NonVoidSettersTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nonvoidsetter/NonVoidSettersTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nonvoidsetter; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for using non-void setters (fluent style) in the target. @@ -32,10 +17,9 @@ * @author Gunnar Morling */ @WithClasses({ Actor.class, ActorDto.class, ActorMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class NonVoidSettersTest { - @Test + @ProcessorTest @IssueKey("353") public void shouldMapAttributeWithoutSetterInSourceType() { ActorDto target = ActorMapper.INSTANCE.actorToActorDto( new Actor( 3, "Hickory Black" ) ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/CustomMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/CustomMapper.java index 31f31d8287..0c2bace6bd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/CustomMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/CustomMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyBigIntWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyBigIntWrapper.java index 70eb0a6387..be6531ff61 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyBigIntWrapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyBigIntWrapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyLongWrapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyLongWrapper.java index f1f5ac6acc..2836f7b3dc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyLongWrapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/MyLongWrapper.java @@ -1,24 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; - /** * @author Sjaak Derksen */ diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullCheckTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullCheckTest.java index 33d5f8fd67..816db7a1dc 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullCheckTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullCheckTest.java @@ -1,30 +1,16 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * Test for correct handling of null checks. @@ -41,10 +27,9 @@ Source.class, Target.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class NullCheckTest { - @Test(expected = NullPointerException.class) + @ProcessorTest @IssueKey("214") public void shouldThrowNullptrWhenCustomMapperIsInvoked() { @@ -53,10 +38,11 @@ public void shouldThrowNullptrWhenCustomMapperIsInvoked() { source.setSomeInteger( 7 ); source.setSomeLong( 2L ); - SourceTargetMapper.INSTANCE.sourceToTarget( source ); + assertThatThrownBy( () -> SourceTargetMapper.INSTANCE.sourceToTarget( source ) ) + .isInstanceOf( NullPointerException.class ); } - @Test + @ProcessorTest @IssueKey("214") public void shouldSurroundTypeConversionWithNullCheck() { @@ -71,7 +57,7 @@ public void shouldSurroundTypeConversionWithNullCheck() { } - @Test + @ProcessorTest @IssueKey("214") public void shouldSurroundArrayListConstructionWithNullCheck() { @@ -85,7 +71,7 @@ public void shouldSurroundArrayListConstructionWithNullCheck() { assertThat( target.getSomeList() ).isNull(); } - @Test + @ProcessorTest @IssueKey("237") public void shouldSurroundConversionPassedToMappingMethodWithNullCheck() { @@ -99,7 +85,7 @@ public void shouldSurroundConversionPassedToMappingMethodWithNullCheck() { assertThat( target.getSomeInteger() ).isNull(); } - @Test + @ProcessorTest @IssueKey("231") public void shouldSurroundConversionFromWrappedPassedToMappingMethodWithPrimitiveArgWithNullCheck() { diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObject.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObject.java index 93b571bcd9..80c1b56a75 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObject.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObject.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObjectMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObjectMapper.java index 37778e82e5..8bb4b9ed38 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObjectMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/NullObjectMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Source.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Source.java index 02092f1009..a1bcc5a5c7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/SourceTargetMapper.java index e2457b35eb..c5f64f611a 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Target.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Target.java index 34777eb28d..aa35d20622 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullcheck; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/AddressBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/AddressBean.java new file mode 100644 index 0000000000..4908d84aa7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/AddressBean.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class AddressBean { + + private String street; + private String city; + + @NonNull + public String getStreet() { + return street; + } + + public void setStreet(String street) { + this.street = street; + } + + @Nullable + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ConstructorTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ConstructorTargetBean.java new file mode 100644 index 0000000000..4ae7de5745 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ConstructorTargetBean.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class ConstructorTargetBean { + + private final String nonNullParam; + private final String nullableParam; + private final String unannotatedParam; + + public ConstructorTargetBean(@NonNull String nonNullParam, + @Nullable String nullableParam, + String unannotatedParam) { + this.nonNullParam = nonNullParam; + this.nullableParam = nullableParam; + this.unannotatedParam = unannotatedParam; + } + + public String getNonNullParam() { + return nonNullParam; + } + + public String getNullableParam() { + return nullableParam; + } + + public String getUnannotatedParam() { + return unannotatedParam; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyConstructorMapper.java new file mode 100644 index 0000000000..b2e2cc0311 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyConstructorMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Erroneous mapper: maps @Nullable source to @NonNull constructor parameter without default value. + */ +@Mapper +public interface ErroneousJSpecifyConstructorMapper { + + ErroneousJSpecifyConstructorMapper INSTANCE = Mappers.getMapper( ErroneousJSpecifyConstructorMapper.class ); + + @Mapping(target = "nonNullParam", source = "nullableValue") + @Mapping(target = "nullableParam", source = "nullableValue") + @Mapping(target = "unannotatedParam", source = "nonNullValue") + ConstructorTargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyDirectParamConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyDirectParamConstructorMapper.java new file mode 100644 index 0000000000..58fc6948a3 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyDirectParamConstructorMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Erroneous mapper: a {@code @Nullable} method parameter is mapped directly (no property entries) + * to a {@code @NonNull} constructor parameter without {@code defaultValue}. + */ +@Mapper +public interface ErroneousJSpecifyDirectParamConstructorMapper { + + ErroneousJSpecifyDirectParamConstructorMapper INSTANCE = + Mappers.getMapper( ErroneousJSpecifyDirectParamConstructorMapper.class ); + + @Mapping(target = "nonNullParam", source = "nullableValue") + @Mapping(target = "nullableParam", source = "nullableValue") + @Mapping(target = "unannotatedParam", source = "nullableValue") + ConstructorTargetBean map(@Nullable String nullableValue); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyUnforgeableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyUnforgeableMapper.java new file mode 100644 index 0000000000..7fb7da3d26 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/ErroneousJSpecifyUnforgeableMapper.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +/** + * Erroneous mapper: the nullable source property cannot be mapped to the target constructor + * parameter's type at all (String -> AddressBean, with no mapping method declared). The + * "cannot find mapping" error must be the only diagnostic; the JSpecify + * "@NonNull constructor parameter" error must not also fire when assignment resolution failed. + */ +@Mapper +public interface ErroneousJSpecifyUnforgeableMapper { + + @Mapping(target = "payload", source = "nullableValue") + UnmappableConstructorTargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/FlatTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/FlatTargetBean.java new file mode 100644 index 0000000000..76e3c02dbd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/FlatTargetBean.java @@ -0,0 +1,59 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; + +public class FlatTargetBean { + + private String street; + private boolean streetSet; + + private String city; + private boolean citySet; + + private String nullableStreet; + private boolean nullableStreetSet; + + public String getStreet() { + return street; + } + + public void setStreet(@NonNull String street) { + this.streetSet = true; + this.street = street; + } + + public boolean isStreetSet() { + return streetSet; + } + + public String getCity() { + return city; + } + + public void setCity(@NonNull String city) { + this.citySet = true; + this.city = city; + } + + public boolean isCitySet() { + return citySet; + } + + public String getNullableStreet() { + return nullableStreet; + } + + public void setNullableStreet(String nullableStreet) { + this.nullableStreetSet = true; + this.nullableStreet = nullableStreet; + } + + public boolean isNullableStreetSet() { + return nullableStreetSet; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyCollectionPropertyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyCollectionPropertyMapper.java new file mode 100644 index 0000000000..d705652832 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyCollectionPropertyMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyCollectionPropertyMapper { + + JSpecifyCollectionPropertyMapper INSTANCE = Mappers.getMapper( JSpecifyCollectionPropertyMapper.class ); + + NullMarkedCollectionTargetBean map(NullMarkedCollectionSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyCollectionPropertyTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyCollectionPropertyTest.java new file mode 100644 index 0000000000..bf194fc08f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyCollectionPropertyTest.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Arrays; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyCollectionPropertyTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedCollectionSourceBean.class, + NullMarkedCollectionTargetBean.class, + JSpecifyCollectionPropertyMapper.class + }) + void collectionPropertyWithNonNullSourceSkipsNullCheck() { + generatedSource.addComparisonToFixtureFor( JSpecifyCollectionPropertyMapper.class ); + + NullMarkedCollectionSourceBean source = new NullMarkedCollectionSourceBean(); + source.setValues( Arrays.asList( "a", "b", "c" ) ); + + NullMarkedCollectionTargetBean target = JSpecifyCollectionPropertyMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getValues() ).containsExactly( "a", "b", "c" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorDefaultValueMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorDefaultValueMapper.java new file mode 100644 index 0000000000..4b3956dccc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorDefaultValueMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * A {@code defaultValue} on the mapping of a {@code @Nullable} source to a {@code @NonNull} + * constructor parameter must suppress the "potentially nullable source" compile error. + */ +@Mapper +public interface JSpecifyConstructorDefaultValueMapper { + + JSpecifyConstructorDefaultValueMapper INSTANCE = + Mappers.getMapper( JSpecifyConstructorDefaultValueMapper.class ); + + @Mapping(target = "nonNullParam", source = "nullableValue", defaultValue = "fallback") + @Mapping(target = "nullableParam", source = "nullableValue") + @Mapping(target = "unannotatedParam", source = "nonNullValue") + ConstructorTargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorMapper.java new file mode 100644 index 0000000000..8791ebfaaa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper with constructor target to test JSpecify on constructor parameters. + * Only valid mappings: @NonNull source to @NonNull target, @Nullable to @Nullable. + */ +@Mapper +public interface JSpecifyConstructorMapper { + + JSpecifyConstructorMapper INSTANCE = Mappers.getMapper( JSpecifyConstructorMapper.class ); + + @Mapping(target = "nonNullParam", source = "nonNullValue") + @Mapping(target = "nullableParam", source = "nullableValue") + @Mapping(target = "unannotatedParam", source = "unannotatedValue") + ConstructorTargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorTest.java new file mode 100644 index 0000000000..9f1cd90fee --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyConstructorTest.java @@ -0,0 +1,124 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for JSpecify nullness annotations with constructor mappings. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithClasses({ + SourceBean.class, + ConstructorTargetBean.class +}) +@WithJSpecify +class JSpecifyConstructorTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses(JSpecifyConstructorMapper.class) + public void verifyGeneratedCode() { + generatedSource.addComparisonToFixtureFor( JSpecifyConstructorMapper.class ); + } + + @ProcessorTest + @WithClasses(JSpecifyConstructorMapper.class) + public void constructorMappingWithNonNullSource() { + SourceBean source = new SourceBean(); + source.setNonNullValue( "value" ); + source.setNullableValue( "nullable" ); + source.setUnannotatedValue( "unannotated" ); + + ConstructorTargetBean target = JSpecifyConstructorMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getNonNullParam() ).isEqualTo( "value" ); + assertThat( target.getNullableParam() ).isEqualTo( "nullable" ); + assertThat( target.getUnannotatedParam() ).isEqualTo( "unannotated" ); + } + + @ProcessorTest + @WithClasses(ErroneousJSpecifyConstructorMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousJSpecifyConstructorMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + message = "Can't map potentially nullable source property \"nullableValue\" to @NonNull " + + "constructor parameter \"nonNullParam\". Consider adding a defaultValue or " + + "defaultExpression.") + }) + public void nullableSourceToNonNullConstructorParamShouldFail() { + } + + @ProcessorTest + @WithClasses(JSpecifyDirectParamConstructorMapper.class) + public void nonNullDirectParameterToNonNullConstructorParamCompiles() { + // A @NonNull method parameter (source has no property entries — it IS the parameter) + // must be accepted by a @NonNull constructor parameter without triggering the + // "potentially nullable source" error. + ConstructorTargetBean target = JSpecifyDirectParamConstructorMapper.INSTANCE.map( + "nn", "nullable", "plain" ); + + assertThat( target.getNonNullParam() ).isEqualTo( "nn" ); + assertThat( target.getNullableParam() ).isEqualTo( "nullable" ); + assertThat( target.getUnannotatedParam() ).isEqualTo( "plain" ); + } + + @ProcessorTest + @WithClasses(ErroneousJSpecifyDirectParamConstructorMapper.class) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousJSpecifyDirectParamConstructorMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + message = "Can't map potentially nullable source property \"nullableValue\" to @NonNull " + + "constructor parameter \"nonNullParam\". Consider adding a defaultValue or " + + "defaultExpression.") + }) + public void nullableDirectParameterToNonNullConstructorParamShouldFail() { + } + + @ProcessorTest + @WithClasses({ AddressBean.class, UnmappableConstructorTargetBean.class, ErroneousJSpecifyUnforgeableMapper.class }) + @ExpectedCompilationOutcome(value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousJSpecifyUnforgeableMapper.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + message = "Can't map property \"String nullableValue\" to \"AddressBean payload\". " + + "Consider to declare/implement a mapping method: \"AddressBean map(String value)\".") + }) + public void failedAssignmentDoesNotAlsoTriggerNullableToNonNullConstructorParamError() { + // The JSpecify @NonNull constructor-param error must not fire when the assignment + // itself could not be resolved; otherwise users see two errors for one underlying issue. + } + + @ProcessorTest + @WithClasses(JSpecifyConstructorDefaultValueMapper.class) + public void defaultValueSuppressesNullableToNonNullConstructorParamError() { + SourceBean source = new SourceBean(); + source.setNonNullValue( "present" ); + // nullableValue left null on purpose — defaultValue "fallback" should kick in. + + ConstructorTargetBean target = JSpecifyConstructorDefaultValueMapper.INSTANCE.map( source ); + + assertThat( target.getNonNullParam() ).isEqualTo( "fallback" ); + assertThat( target.getUnannotatedParam() ).isEqualTo( "present" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDirectParamConstructorMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDirectParamConstructorMapper.java new file mode 100644 index 0000000000..4bb49a5f5d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDirectParamConstructorMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper that maps direct method parameters (no property entries) to constructor parameters. + * Verifies that a {@code @NonNull} source parameter is accepted by a {@code @NonNull} + * constructor parameter target. + */ +@Mapper +public interface JSpecifyDirectParamConstructorMapper { + + JSpecifyDirectParamConstructorMapper INSTANCE = Mappers.getMapper( JSpecifyDirectParamConstructorMapper.class ); + + @Mapping(target = "nonNullParam", source = "nonNullValue") + @Mapping(target = "nullableParam", source = "nullableValue") + @Mapping(target = "unannotatedParam", source = "unannotatedValue") + ConstructorTargetBean map(@NonNull String nonNullValue, + @Nullable String nullableValue, + String unannotatedValue); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledContainerSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledContainerSourceMapper.java new file mode 100644 index 0000000000..2de32c4235 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledContainerSourceMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * Dedicated to {@link JSpecifyDisabledTest} so its generated implementation is not shared (and pre-loaded) by an + * enabled test in the same JVM. With JSpecify enabled the {@code @NonNull} source would skip the method-level guard. + */ +@NullMarked +@Mapper +public interface JSpecifyDisabledContainerSourceMapper { + + JSpecifyDisabledContainerSourceMapper INSTANCE = + Mappers.getMapper( JSpecifyDisabledContainerSourceMapper.class ); + + List mapAll(List sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledMapper.java new file mode 100644 index 0000000000..08a5fe3c37 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * Dedicated mapper for {@link JSpecifyDisabledTest} so that the test's JSpecify-disabled + * compilation result is isolated from tests that share {@link JSpecifyNullCheckMapper} and + * would otherwise keep the JSpecify-enabled {@code INSTANCE} cached in the JVM. + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JSpecifyDisabledMapper { + + JSpecifyDisabledMapper INSTANCE = Mappers.getMapper( JSpecifyDisabledMapper.class ); + + @Mapping(target = "nonNullTargetFromNullable", source = "nullableValue") + TargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledNonNullReturnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledNonNullReturnMapper.java new file mode 100644 index 0000000000..bcdb0bc0ca --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledNonNullReturnMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * Dedicated to {@link JSpecifyDisabledTest} so its generated implementation is not shared (and pre-loaded) by an + * enabled test in the same JVM. With JSpecify enabled the {@code @NonNull} return would force RETURN_DEFAULT. + */ +@NullMarked +@Mapper +public interface JSpecifyDisabledNonNullReturnMapper { + + JSpecifyDisabledNonNullReturnMapper INSTANCE = + Mappers.getMapper( JSpecifyDisabledNonNullReturnMapper.class ); + + List mapAll(@Nullable List sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledTest.java new file mode 100644 index 0000000000..d669952737 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyDisabledTest.java @@ -0,0 +1,83 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Verifies that {@code -Amapstruct.disableJSpecify=true} fully opts out of JSpecify-based + * null-check inference. With the flag on, mappers that would normally be affected by + * JSpecify fall back to the pre-JSpecify baseline. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithJSpecify +@ProcessorOption(name = "mapstruct.disableJSpecify", value = "true") +class JSpecifyDisabledTest { + + @ProcessorTest + @WithClasses({ SourceBean.class, TargetBean.class, JSpecifyDisabledMapper.class }) + public void disabledFlagSkipsTargetNonNullInference() { + // With JSpecify enabled, mapping a @Nullable source onto a @NonNull target setter + // emits an "if (src != null)" guard. When disabled, the default NullValueCheckStrategy + // (ON_IMPLICIT_CONVERSION) applies and a direct String->String assignment gets no guard, + // so the setter is always invoked — even when the source is null. + SourceBean source = new SourceBean(); + // nullableValue left null + + TargetBean target = JSpecifyDisabledMapper.INSTANCE.map( source ); + + assertThat( target.isNonNullTargetFromNullableSet() ).isTrue(); + assertThat( target.getNonNullTargetFromNullable() ).isNull(); + } + + @ProcessorTest + @WithClasses({ + SourceBean.class, + ConstructorTargetBean.class, + ErroneousJSpecifyConstructorMapper.class + }) + @ExpectedCompilationOutcome(value = CompilationResult.SUCCEEDED) + public void disabledFlagSkipsConstructorNonNullHardError() { + // The JSpecify-driven hard error for a @Nullable source mapped to a @NonNull constructor + // parameter is purely a JSpecify signal; with the flag disabled it must not be raised. + } + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyDisabledContainerSourceMapper.class + }) + public void disabledFlagKeepsContainerMethodSourceGuard() { + // With JSpecify enabled the @NonNull source parameter skips the method-level null guard. When disabled, + // the resolver reports UNKNOWN, so the unconditional "if (sources == null) return null;" guard is kept and + // mapping a null source returns null rather than throwing an NPE. + assertThat( JSpecifyDisabledContainerSourceMapper.INSTANCE.mapAll( null ) ).isNull(); + } + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyDisabledNonNullReturnMapper.class + }) + public void disabledFlagSkipsNonNullReturnForcing() { + // With JSpecify enabled the @NonNull return forces RETURN_DEFAULT (empty list for a null source). When + // disabled, that forcing is suppressed and the default RETURN_NULL strategy applies, so a null source + // maps to null. + assertThat( JSpecifyDisabledNonNullReturnMapper.INSTANCE.mapAll( null ) ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyIterableMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyIterableMethodMapper.java new file mode 100644 index 0000000000..5a1d0b0d68 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyIterableMethodMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyIterableMethodMapper { + + JSpecifyIterableMethodMapper INSTANCE = Mappers.getMapper( JSpecifyIterableMethodMapper.class ); + + List mapAll(List sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyIterableMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyIterableMethodTest.java new file mode 100644 index 0000000000..ceed2236f6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyIterableMethodTest.java @@ -0,0 +1,44 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyIterableMethodTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyIterableMethodMapper.class + }) + void iterableMethodWithNonNullSourceSkipsMethodGuard() { + generatedSource.addComparisonToFixtureFor( JSpecifyIterableMethodMapper.class ); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + List targets = JSpecifyIterableMethodMapper.INSTANCE.mapAll( Arrays.asList( source ) ); + + assertThat( targets ).hasSize( 1 ); + assertThat( targets.get( 0 ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyMapMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyMapMethodMapper.java new file mode 100644 index 0000000000..cdb844795b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyMapMethodMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Map; + +import org.jspecify.annotations.NullMarked; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyMapMethodMapper { + + JSpecifyMapMethodMapper INSTANCE = Mappers.getMapper( JSpecifyMapMethodMapper.class ); + + Map mapAll(Map sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyMapMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyMapMethodTest.java new file mode 100644 index 0000000000..4673841873 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyMapMethodTest.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyMapMethodTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyMapMethodMapper.class + }) + void mapMethodWithNonNullSourceSkipsMethodGuard() { + generatedSource.addComparisonToFixtureFor( JSpecifyMapMethodMapper.class ); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + Map targets = + JSpecifyMapMethodMapper.INSTANCE.mapAll( Collections.singletonMap( "k", source ) ); + + assertThat( targets ).hasSize( 1 ); + assertThat( targets.get( "k" ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNestedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNestedMapper.java new file mode 100644 index 0000000000..6d5e005446 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNestedMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper with nested property chains and JSpecify annotations. + * Tests that the deepest property's annotation is used for the null check decision. + */ +@Mapper +public interface JSpecifyNestedMapper { + + JSpecifyNestedMapper INSTANCE = Mappers.getMapper( JSpecifyNestedMapper.class ); + + // nonNullAddress.street: leaf @NonNull -> target @NonNull -> skip null check (source @NonNull) + @Mapping(target = "street", source = "nonNullAddress.street") + // nonNullAddress.city: leaf @Nullable -> target @NonNull -> null check + @Mapping(target = "city", source = "nonNullAddress.city") + // nonNullAddress.street: leaf @NonNull -> target unannotated -> skip null check (source @NonNull) + @Mapping(target = "nullableStreet", source = "nonNullAddress.street") + FlatTargetBean map(NestedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNestedTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNestedTest.java new file mode 100644 index 0000000000..a17c882da1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNestedTest.java @@ -0,0 +1,83 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for JSpecify nullness annotations with nested property chains. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithClasses({ + AddressBean.class, + NestedSourceBean.class, + FlatTargetBean.class, + JSpecifyNestedMapper.class +}) +@WithJSpecify +class JSpecifyNestedTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void verifyGeneratedCode() { + generatedSource.addComparisonToFixtureFor( JSpecifyNestedMapper.class ); + } + + @ProcessorTest + public void nestedNonNullLeafSkipsNullCheck() { + AddressBean address = new AddressBean(); + address.setStreet( "Main St" ); + + NestedSourceBean source = new NestedSourceBean(); + source.setNonNullAddress( address ); + + FlatTargetBean target = JSpecifyNestedMapper.INSTANCE.map( source ); + + assertThat( target.isStreetSet() ).isTrue(); + assertThat( target.getStreet() ).isEqualTo( "Main St" ); + } + + @ProcessorTest + public void nestedNullableLeafToNonNullTargetAddsNullCheck() { + AddressBean address = new AddressBean(); + // city is null (@Nullable) + + NestedSourceBean source = new NestedSourceBean(); + source.setNonNullAddress( address ); + + FlatTargetBean target = JSpecifyNestedMapper.INSTANCE.map( source ); + + // city: source @Nullable -> target @NonNull -> null check -> setter not called + assertThat( target.isCitySet() ).isFalse(); + } + + @ProcessorTest + @WithClasses(JSpecifyNullableIntermediateMapper.class) + public void nullableIntermediateMustNotSkipNullCheckOnNonNullLeaf() { + generatedSource.addComparisonToFixtureFor( JSpecifyNullableIntermediateMapper.class ); + + // nullableAddress is @Nullable; its street is @NonNull; target setter is @NonNull. + // When the intermediate is null, the whole source chain yields null and the @NonNull + // target setter must NOT be invoked. + NestedSourceBean source = new NestedSourceBean(); + // nullableAddress stays null + + FlatTargetBean target = JSpecifyNullableIntermediateMapper.INSTANCE.map( source ); + + assertThat( target.isStreetSet() ).isFalse(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullParamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullParamMapper.java new file mode 100644 index 0000000000..44be48f9a8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullParamMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper for testing JSpecify @NonNull on source parameter. + * The method-level null guard (if source == null return null) should be skipped. + */ +@Mapper +public interface JSpecifyNonNullParamMapper { + + JSpecifyNonNullParamMapper INSTANCE = Mappers.getMapper( JSpecifyNonNullParamMapper.class ); + + @Mapping(target = "nonNullTarget", source = "nonNullValue") + @Mapping(target = "nullableTarget", source = "nullableValue") + @Mapping(target = "unannotatedTarget", source = "unannotatedValue") + @Mapping(target = "nonNullTargetFromNullable", source = "nullableValue") + TargetBean map(@NonNull SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanMapper.java new file mode 100644 index 0000000000..8401e56682 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyNonNullReturnBeanMapper { + + JSpecifyNonNullReturnBeanMapper INSTANCE = Mappers.getMapper( JSpecifyNonNullReturnBeanMapper.class ); + + @BeanMapping(ignoreByDefault = true) + @Mapping(target = "nonNullByDefault", source = "value") + NullMarkedTargetBean map(@Nullable JSpecifyNonNullReturnBeanSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanSourceBean.java new file mode 100644 index 0000000000..d4bdb926c5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanSourceBean.java @@ -0,0 +1,22 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class JSpecifyNonNullReturnBeanSourceBean { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanTest.java new file mode 100644 index 0000000000..ccac0e0653 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnBeanTest.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyNonNullReturnBeanTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + JSpecifyNonNullReturnBeanSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNonNullReturnBeanMapper.class + }) + void nonNullReturnForcesMapNullToDefault() { + generatedSource.addComparisonToFixtureFor( JSpecifyNonNullReturnBeanMapper.class ); + + NullMarkedTargetBean fromNull = JSpecifyNonNullReturnBeanMapper.INSTANCE.map( null ); + + assertThat( fromNull ).isNotNull(); + assertThat( fromNull.getNonNullByDefault() ).isNull(); + + JSpecifyNonNullReturnBeanSourceBean source = new JSpecifyNonNullReturnBeanSourceBean(); + source.setValue( "value" ); + + NullMarkedTargetBean fromSource = JSpecifyNonNullReturnBeanMapper.INSTANCE.map( source ); + + assertThat( fromSource ).isNotNull(); + assertThat( fromSource.getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnIterableMapper.java new file mode 100644 index 0000000000..4f3fd1c0e2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnIterableMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyNonNullReturnIterableMapper { + + JSpecifyNonNullReturnIterableMapper INSTANCE = Mappers.getMapper( JSpecifyNonNullReturnIterableMapper.class ); + + List mapAll(@Nullable List sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnIterableTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnIterableTest.java new file mode 100644 index 0000000000..f4ba29bb92 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnIterableTest.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyNonNullReturnIterableTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNonNullReturnIterableMapper.class + }) + void nonNullReturnIterableForcesEmptyDefault() { + generatedSource.addComparisonToFixtureFor( JSpecifyNonNullReturnIterableMapper.class ); + + List fromNull = JSpecifyNonNullReturnIterableMapper.INSTANCE.mapAll( null ); + + assertThat( fromNull ).isEmpty(); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + List fromSource = + JSpecifyNonNullReturnIterableMapper.INSTANCE.mapAll( Arrays.asList( source ) ); + + assertThat( fromSource ).hasSize( 1 ); + assertThat( fromSource.get( 0 ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnMapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnMapMapper.java new file mode 100644 index 0000000000..8e6a0cb885 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnMapMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Map; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyNonNullReturnMapMapper { + + JSpecifyNonNullReturnMapMapper INSTANCE = Mappers.getMapper( JSpecifyNonNullReturnMapMapper.class ); + + Map mapAll(@Nullable Map sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnMapTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnMapTest.java new file mode 100644 index 0000000000..b96d3f3fc0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnMapTest.java @@ -0,0 +1,49 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Collections; +import java.util.Map; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyNonNullReturnMapTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNonNullReturnMapMapper.class + }) + void nonNullReturnMapForcesEmptyDefault() { + generatedSource.addComparisonToFixtureFor( JSpecifyNonNullReturnMapMapper.class ); + + Map fromNull = JSpecifyNonNullReturnMapMapper.INSTANCE.mapAll( null ); + + assertThat( fromNull ).isEmpty(); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + Map fromSource = + JSpecifyNonNullReturnMapMapper.INSTANCE.mapAll( Collections.singletonMap( "k", source ) ); + + assertThat( fromSource ).hasSize( 1 ); + assertThat( fromSource.get( "k" ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnStreamMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnStreamMapper.java new file mode 100644 index 0000000000..62d061a001 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnStreamMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.stream.Stream; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyNonNullReturnStreamMapper { + + JSpecifyNonNullReturnStreamMapper INSTANCE = Mappers.getMapper( JSpecifyNonNullReturnStreamMapper.class ); + + Stream mapAll(@Nullable Stream sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnStreamTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnStreamTest.java new file mode 100644 index 0000000000..fa62973ebf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnStreamTest.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyNonNullReturnStreamTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNonNullReturnStreamMapper.class + }) + void nonNullReturnStreamForcesEmptyDefault() { + generatedSource.addComparisonToFixtureFor( JSpecifyNonNullReturnStreamMapper.class ); + + Stream fromNull = JSpecifyNonNullReturnStreamMapper.INSTANCE.mapAll( null ); + + assertThat( fromNull ).isNotNull(); + assertThat( fromNull.collect( Collectors.toList() ) ).isEmpty(); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + List fromSource = JSpecifyNonNullReturnStreamMapper.INSTANCE + .mapAll( Stream.of( source ) ) + .collect( Collectors.toList() ); + + assertThat( fromSource ).hasSize( 1 ); + assertThat( fromSource.get( 0 ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnUpdateIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnUpdateIterableMapper.java new file mode 100644 index 0000000000..b79763d712 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnUpdateIterableMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyNonNullReturnUpdateIterableMapper { + + JSpecifyNonNullReturnUpdateIterableMapper INSTANCE = + Mappers.getMapper( JSpecifyNonNullReturnUpdateIterableMapper.class ); + + List mapAll(@Nullable List sources, + @MappingTarget List target); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnUpdateIterableTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnUpdateIterableTest.java new file mode 100644 index 0000000000..56e71e6995 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNonNullReturnUpdateIterableTest.java @@ -0,0 +1,46 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * The @NonNull-return forcing is gated on {@code !isUpdateMethod()}. An update (existing-instance) method must not + * be forced to RETURN_DEFAULT: a null source returns the supplied target instance, not a fresh empty collection. + */ +@IssueKey("1243") +@WithJSpecify +class JSpecifyNonNullReturnUpdateIterableTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNonNullReturnUpdateIterableMapper.class + }) + void updateMethodWithNonNullReturnIsNotForced() { + generatedSource.addComparisonToFixtureFor( JSpecifyNonNullReturnUpdateIterableMapper.class ); + + List target = new ArrayList<>(); + + List result = JSpecifyNonNullReturnUpdateIterableMapper.INSTANCE.mapAll( null, target ); + + assertThat( result ).isSameAs( target ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullCheckMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullCheckMapper.java new file mode 100644 index 0000000000..8253aca89b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullCheckMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper for testing JSpecify nullness annotation support on property level. + */ +@Mapper +public interface JSpecifyNullCheckMapper { + + JSpecifyNullCheckMapper INSTANCE = Mappers.getMapper( JSpecifyNullCheckMapper.class ); + + @Mapping(target = "nonNullTarget", source = "nonNullValue") + @Mapping(target = "nullableTarget", source = "nullableValue") + @Mapping(target = "unannotatedTarget", source = "unannotatedValue") + @Mapping(target = "nonNullTargetFromNullable", source = "nullableValue") + TargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullCheckTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullCheckTest.java new file mode 100644 index 0000000000..4b3e11dbdd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullCheckTest.java @@ -0,0 +1,125 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatNullPointerException; + +/** + * Tests for JSpecify nullness annotation support in MapStruct. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithClasses({ + SourceBean.class, + TargetBean.class +}) +@WithJSpecify +class JSpecifyNullCheckTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + // -- Property-level tests (JSpecifyNullCheckMapper) -- + + @ProcessorTest + @WithClasses(JSpecifyNullCheckMapper.class) + public void sourceNonNullGetterShouldSkipNullCheck() { + generatedSource.addComparisonToFixtureFor( JSpecifyNullCheckMapper.class ); + + // Source @NonNull getter -> no null check, setter always called + SourceBean source = new SourceBean(); + source.setNonNullValue( "value" ); + + TargetBean target = JSpecifyNullCheckMapper.INSTANCE.map( source ); + + assertThat( target.isNonNullTargetSet() ).isTrue(); + assertThat( target.getNonNullTarget() ).isEqualTo( "value" ); + } + + @ProcessorTest + @WithClasses(JSpecifyNullCheckMapper.class) + public void sourceNullableTargetNonNullShouldAddNullCheck() { + // Source @Nullable getter + Target @NonNull setter -> null check added + // When source value is null, setter should NOT be called + SourceBean source = new SourceBean(); + + TargetBean target = JSpecifyNullCheckMapper.INSTANCE.map( source ); + + assertThat( target.isNonNullTargetFromNullableSet() ).isFalse(); + } + + @ProcessorTest + @WithClasses(JSpecifyNullCheckMapper.class) + public void sourceNullableTargetNullableDefersToStrategy() { + // Source @Nullable + Target @Nullable -> defers to NullValueCheckStrategy + // Default NVCS is ON_IMPLICIT_CONVERSION, direct String->String has no null check + SourceBean source = new SourceBean(); + + TargetBean target = JSpecifyNullCheckMapper.INSTANCE.map( source ); + + // With ON_IMPLICIT_CONVERSION, no null check for direct assignment -> setter called + assertThat( target.isNullableTargetSet() ).isTrue(); + } + + // -- JSpecify overrides NullValueCheckStrategy -- + + @ProcessorTest + @WithClasses(JSpecifyOverridesStrategyMapper.class) + public void jspecifyOverridesNullValueCheckStrategyAlways() { + generatedSource.addComparisonToFixtureFor( JSpecifyOverridesStrategyMapper.class ); + + // Even with NullValueCheckStrategy.ALWAYS, source @NonNull should skip null check + SourceBean source = new SourceBean(); + source.setNonNullValue( "value" ); + + TargetBean target = JSpecifyOverridesStrategyMapper.INSTANCE.map( source ); + + assertThat( target.isNonNullTargetSet() ).isTrue(); + } + + // -- Method-level parameter null check -- + + @ProcessorTest + @WithClasses(JSpecifyNonNullParamMapper.class) + public void nonNullParamShouldSkipMethodLevelNullGuard() { + generatedSource.addComparisonToFixtureFor( JSpecifyNonNullParamMapper.class ); + + // Non-null input: mapper maps through normally. + SourceBean source = new SourceBean(); + source.setNonNullValue( "value" ); + source.setUnannotatedValue( "plain" ); + + TargetBean target = JSpecifyNonNullParamMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + assertThat( target.getNonNullTarget() ).isEqualTo( "value" ); + assertThat( target.getUnannotatedTarget() ).isEqualTo( "plain" ); + + // Null input: because the method-level guard was skipped, the mapper must dereference + // the source and throw NPE rather than silently returning null. + assertThatNullPointerException().isThrownBy( () -> JSpecifyNonNullParamMapper.INSTANCE.map( null ) ); + } + + @ProcessorTest + @WithClasses(JSpecifyNullCheckMapper.class) + public void unannotatedParamShouldHaveMethodLevelNullGuard() { + // Unannotated source parameter -> normal "if (source == null) return null" guard + SourceBean source = new SourceBean(); + + TargetBean target = JSpecifyNullCheckMapper.INSTANCE.map( source ); + + assertThat( target ).isNotNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullMarkedTargetScopeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullMarkedTargetScopeMapper.java new file mode 100644 index 0000000000..cdbbdf7e82 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullMarkedTargetScopeMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Target is a {@code @NullMarked} bean with an unannotated setter parameter + * ({@code setNonNullByDefault}), which JSpecify semantics promote to {@code @NonNull}. + * The source getter is explicitly {@code @Nullable}, so a null check must be generated. + */ +@Mapper +public interface JSpecifyNullMarkedTargetScopeMapper { + + JSpecifyNullMarkedTargetScopeMapper INSTANCE = + Mappers.getMapper( JSpecifyNullMarkedTargetScopeMapper.class ); + + @Mapping(target = "nonNullByDefault", source = "nullableValue") + @Mapping(target = "explicitlyNullable", ignore = true) + NullMarkedTargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullMarkedTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullMarkedTest.java new file mode 100644 index 0000000000..e41aa5dece --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullMarkedTest.java @@ -0,0 +1,188 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage.PackageNullMarkedMapper; +import org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage.PackageNullMarkedSourceBean; +import org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage.PackageNullMarkedTargetBean; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.WithPackageInfo; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for JSpecify {@code @NullMarked} / {@code @NullUnmarked} support. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithJSpecify +class JSpecifyNullMarkedTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ NullMarkedSourceBean.class, NullMarkedTargetBean.class, NullMarkedMapper.class }) + public void nullMarkedSourceAndTarget() { + generatedSource.addComparisonToFixtureFor( NullMarkedMapper.class ); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + NullMarkedTargetBean target = NullMarkedMapper.INSTANCE.map( source ); + + // nonNullByDefault: source effectively @NonNull -> skip null check -> setter called + assertThat( target.isNonNullByDefaultSet() ).isTrue(); + assertThat( target.getNonNullByDefault() ).isEqualTo( "value" ); + } + + @ProcessorTest + @WithClasses({ NullMarkedSourceBean.class, NullMarkedTargetBean.class, NullMarkedMapper.class }) + public void nullMarkedNullableSourceToNonNullTarget() { + // @Nullable getter -> target effectively @NonNull -> null check added + NullMarkedSourceBean source = new NullMarkedSourceBean(); + // explicitlyNullable is null + + NullMarkedTargetBean target = NullMarkedMapper.INSTANCE.map( source ); + + // Target's setter for explicitlyNullable is @Nullable -> defers to strategy + // Default NVCS = ON_IMPLICIT_CONVERSION, direct String -> String -> no null check + assertThat( target.isExplicitlyNullableSet() ).isTrue(); + } + + @ProcessorTest + @WithClasses({ NullMarkedSourceBean.class, TargetBean.class, NullMarkedSourceToPlainTargetMapper.class }) + public void nullMarkedSourceToPlainTarget() { + generatedSource.addComparisonToFixtureFor( NullMarkedSourceToPlainTargetMapper.class ); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + TargetBean target = NullMarkedSourceToPlainTargetMapper.INSTANCE.map( source ); + + // Source effectively @NonNull -> skip null check -> setter always called + assertThat( target.isUnannotatedTargetSet() ).isTrue(); + } + + @ProcessorTest + @WithClasses({ NullMarkedSourceBean.class, NullMarkedTargetBean.class, NullMarkedMapperWithParam.class }) + public void nullMarkedMapperSkipsMethodLevelNullGuard() { + generatedSource.addComparisonToFixtureFor( NullMarkedMapperWithParam.class ); + } + + @ProcessorTest + @WithClasses({ + PackageNullMarkedSourceBean.class, + PackageNullMarkedTargetBean.class, + PackageNullMarkedMapper.class + }) + @WithPackageInfo(PackageNullMarkedSourceBean.class) + public void packageLevelNullMarked() { + generatedSource.addComparisonToFixtureFor( PackageNullMarkedMapper.class ); + + // @NullMarked package: unannotated types are effectively @NonNull. + // Mapper uses NullValueCheckStrategy.ALWAYS but JSpecify wins -> no null checks. + PackageNullMarkedSourceBean source = new PackageNullMarkedSourceBean(); + // value is null + + PackageNullMarkedTargetBean target = PackageNullMarkedMapper.INSTANCE.map( source ); + + // Unannotated getter is effectively @NonNull -> no null check despite ALWAYS strategy + // -> setter is called even when source value is null + assertThat( target.isValueSet() ).isTrue(); + } + + @ProcessorTest + @WithClasses({ + SourceBean.class, + TargetBean.class, + JSpecifyNullUnmarkedMethodMapper.class + }) + public void nullUnmarkedOnMethodReversesEnclosingNullMarkedScope() { + // The mapper interface is @NullMarked but the method is @NullUnmarked. The source + // parameter is unannotated: with method-level scope, its nullability must be UNKNOWN + // (not promoted), so the method-level null guard is generated. Passing null must + // return null rather than NPE. + TargetBean target = JSpecifyNullUnmarkedMethodMapper.INSTANCE.map( null ); + + assertThat( target ).isNull(); + } + + @ProcessorTest + @WithClasses({ + NullUnmarkedSourceBean.class, + TargetBean.class, + JSpecifyNullUnmarkedMapper.class + }) + public void nullUnmarkedReversesEnclosingNullMarkedScope() { + // The source class is @NullUnmarked inside a @NullMarked outer class. + // Unannotated getter must be UNKNOWN, not promoted to @NonNull. + // With NVCS=ALWAYS, a null check is generated and the setter is NOT called when source is null. + NullUnmarkedSourceBean.Inner source = new NullUnmarkedSourceBean.Inner(); + // value is null + + TargetBean target = JSpecifyNullUnmarkedMapper.INSTANCE.map( source ); + + assertThat( target.isUnannotatedTargetSet() ).isFalse(); + } + + @ProcessorTest + @WithClasses({ + SourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNullMarkedTargetScopeMapper.class + }) + public void nullMarkedTargetPromotesUnannotatedSetterParamToNonNull() { + // Target bean is @NullMarked; setNonNullByDefault has an unannotated String parameter + // which must be treated as @NonNull by JSpecify semantics. Source getter is @Nullable, + // so a null check must be generated and the setter must NOT be called when source is null. + SourceBean source = new SourceBean(); + // nullableValue is null + + NullMarkedTargetBean target = JSpecifyNullMarkedTargetScopeMapper.INSTANCE.map( source ); + + assertThat( target.isNonNullByDefaultSet() ).isFalse(); + } + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + TargetBean.class, + JSpecifyNullableOverridesScopeMapper.class + }) + public void explicitNullableOverridesNullMarkedScope() { + // Source getter is explicitly @Nullable inside a @NullMarked class — the explicit + // annotation must keep the source NULLABLE instead of being promoted to @NonNull + // by the scope. Target setter is explicitly @NonNull, so a null check is required. + NullMarkedSourceBean source = new NullMarkedSourceBean(); + // explicitlyNullable is null + + TargetBean target = JSpecifyNullableOverridesScopeMapper.INSTANCE.map( source ); + + // Null check generated -> setter must NOT be called when source value is null. + assertThat( target.isNonNullTargetFromNullableSet() ).isFalse(); + } + + @ProcessorTest + @WithClasses({ + PackageNullMarkedSourceBean.class, + PackageNullMarkedTargetBean.class, + PackageNullMarkedMapper.class + }) + public void packageLevelNullMarkedWithoutPackageInfo() { + // Same classes and mapper as packageLevelNullMarked but WITHOUT @WithPackageInfo. + // Without the package-info.java being compiled, @NullMarked is not visible — + // unannotated types have unknown nullability and the ALWAYS strategy produces null checks. + generatedSource.addComparisonToFixtureFor( PackageNullMarkedMapper.class, "withoutPackageInfo" ); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullUnmarkedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullUnmarkedMapper.java new file mode 100644 index 0000000000..defce89a61 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullUnmarkedMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * Source is a {@code @NullUnmarked} class nested inside a {@code @NullMarked} outer class. + * The unannotated getter must be treated as unknown nullability (not promoted to {@code @NonNull}). + * With {@code NullValueCheckStrategy.ALWAYS}, a null check must be generated. + */ +@Mapper( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +public interface JSpecifyNullUnmarkedMapper { + + JSpecifyNullUnmarkedMapper INSTANCE = Mappers.getMapper( JSpecifyNullUnmarkedMapper.class ); + + @Mapping(target = "unannotatedTarget", source = "value") + TargetBean map(NullUnmarkedSourceBean.Inner source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullUnmarkedMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullUnmarkedMethodMapper.java new file mode 100644 index 0000000000..11f24a2934 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullUnmarkedMethodMapper.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * Mapper interface annotated with {@code @NullMarked} but the mapping method itself is + * {@code @NullUnmarked}. The unannotated source parameter inside the {@code @NullUnmarked} + * method must be treated as unknown nullability, so with {@code NullValueCheckStrategy.ALWAYS} + * the method-level null guard must still be generated. + */ +@NullMarked +@Mapper( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS, + unmappedTargetPolicy = ReportingPolicy.IGNORE +) +public interface JSpecifyNullUnmarkedMethodMapper { + + JSpecifyNullUnmarkedMethodMapper INSTANCE = Mappers.getMapper( JSpecifyNullUnmarkedMethodMapper.class ); + + @NullUnmarked + @Mapping(target = "unannotatedTarget", source = "unannotatedValue") + TargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableIntermediateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableIntermediateMapper.java new file mode 100644 index 0000000000..1c6571a6a7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableIntermediateMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * Nested source chain where the intermediate accessor is {@code @Nullable} but the deepest + * accessor is {@code @NonNull}. The target setter is {@code @NonNull} — when the intermediate + * returns null, the setter must not be invoked. + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JSpecifyNullableIntermediateMapper { + + JSpecifyNullableIntermediateMapper INSTANCE = Mappers.getMapper( JSpecifyNullableIntermediateMapper.class ); + + // nullableAddress is @Nullable; street is @NonNull; target setStreet is @NonNull. + // Because the intermediate can be null, the null check must not be skipped. + @Mapping(target = "street", source = "nullableAddress.street") + FlatTargetBean map(NestedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableOverridesScopeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableOverridesScopeMapper.java new file mode 100644 index 0000000000..08f8cba72e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableOverridesScopeMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; +import org.mapstruct.factory.Mappers; + +/** + * Maps an explicitly {@code @Nullable} source property inside a {@code @NullMarked} scope + * to a {@code @NonNull} setter parameter. A null check must be generated because the + * explicit {@code @Nullable} overrides the enclosing {@code @NullMarked} scope, keeping + * the source nullability as {@code NULLABLE} instead of being promoted to {@code NON_NULL}. + */ +@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface JSpecifyNullableOverridesScopeMapper { + + JSpecifyNullableOverridesScopeMapper INSTANCE = + Mappers.getMapper( JSpecifyNullableOverridesScopeMapper.class ); + + @Mapping(target = "nonNullTargetFromNullable", source = "explicitlyNullable") + TargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableSourceIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableSourceIterableMapper.java new file mode 100644 index 0000000000..026890dee8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableSourceIterableMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyNullableSourceIterableMapper { + + JSpecifyNullableSourceIterableMapper INSTANCE = Mappers.getMapper( JSpecifyNullableSourceIterableMapper.class ); + + @Nullable + List mapAll(@Nullable List sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableSourceIterableTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableSourceIterableTest.java new file mode 100644 index 0000000000..da77fe71e1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyNullableSourceIterableTest.java @@ -0,0 +1,52 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.Arrays; +import java.util.List; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Negative counterpart to {@link JSpecifyIterableMethodTest}: a {@code @Nullable} source parameter (and a + * {@code @Nullable} return, so the @NonNull-return forcing does not kick in) must keep the method-level + * {@code if ( sources == null ) return null;} guard. + */ +@IssueKey("1243") +@WithJSpecify +class JSpecifyNullableSourceIterableTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyNullableSourceIterableMapper.class + }) + void nullableSourceKeepsMethodGuard() { + generatedSource.addComparisonToFixtureFor( JSpecifyNullableSourceIterableMapper.class ); + + assertThat( JSpecifyNullableSourceIterableMapper.INSTANCE.mapAll( null ) ).isNull(); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + List targets = + JSpecifyNullableSourceIterableMapper.INSTANCE.mapAll( Arrays.asList( source ) ); + + assertThat( targets ).hasSize( 1 ); + assertThat( targets.get( 0 ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyOverridesStrategyMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyOverridesStrategyMapper.java new file mode 100644 index 0000000000..97303bc7ef --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyOverridesStrategyMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +/** + * Mapper with NullValueCheckStrategy.ALWAYS that should be overridden by JSpecify annotations. + * Source @NonNull getter -> should NOT have null check despite ALWAYS strategy. + */ +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface JSpecifyOverridesStrategyMapper { + + JSpecifyOverridesStrategyMapper INSTANCE = Mappers.getMapper( JSpecifyOverridesStrategyMapper.class ); + + @Mapping(target = "nonNullTarget", source = "nonNullValue") + @Mapping(target = "nullableTarget", source = "nullableValue") + @Mapping(target = "unannotatedTarget", source = "unannotatedValue") + @Mapping(target = "nonNullTargetFromNullable", source = "nullableValue") + TargetBean map(SourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyReturnNullOverrideIterableMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyReturnNullOverrideIterableMapper.java new file mode 100644 index 0000000000..387103bae5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyReturnNullOverrideIterableMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; +import org.mapstruct.IterableMapping; +import org.mapstruct.Mapper; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyReturnNullOverrideIterableMapper { + + JSpecifyReturnNullOverrideIterableMapper INSTANCE = + Mappers.getMapper( JSpecifyReturnNullOverrideIterableMapper.class ); + + // Explicit RETURN_NULL, but the @NonNull return type (NullMarked scope) wins and forces RETURN_DEFAULT. + @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_NULL) + List mapAll(@Nullable List sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyReturnNullOverrideIterableTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyReturnNullOverrideIterableTest.java new file mode 100644 index 0000000000..eaea578903 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyReturnNullOverrideIterableTest.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Verifies that a JSpecify {@code @NonNull} return type wins over an explicitly configured + * {@code NullValueMappingStrategy.RETURN_NULL}: the generated method returns an empty collection rather + * than {@code null}. + */ +@IssueKey("1243") +@WithJSpecify +class JSpecifyReturnNullOverrideIterableTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyReturnNullOverrideIterableMapper.class + }) + void nonNullReturnOverridesExplicitReturnNull() { + generatedSource.addComparisonToFixtureFor( JSpecifyReturnNullOverrideIterableMapper.class ); + + assertThat( JSpecifyReturnNullOverrideIterableMapper.INSTANCE.mapAll( null ) ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifySafetyGuardMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifySafetyGuardMapper.java new file mode 100644 index 0000000000..1be36485e5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifySafetyGuardMapper.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * Verifies that existing safety guards still trigger a null check when the source is + * {@code @Nullable}: + *

          + *
        • Unboxing ({@code Integer} -> {@code int})
        • + *
        • {@code defaultValue}
        • + *
        • {@link NullValuePropertyMappingStrategy#SET_TO_DEFAULT} on an update method
        • + *
        + */ +@Mapper +public interface JSpecifySafetyGuardMapper { + + JSpecifySafetyGuardMapper INSTANCE = Mappers.getMapper( JSpecifySafetyGuardMapper.class ); + + @Mapping(target = "unboxedNumber", source = "nullableNumber") + @Mapping(target = "textWithDefault", source = "nullableText", defaultValue = "default") + @Mapping(target = "textWithNvpms", ignore = true) + SafetyGuardTargetBean map(SafetyGuardSourceBean source); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) + @Mapping(target = "unboxedNumber", ignore = true) + @Mapping(target = "textWithDefault", ignore = true) + @Mapping(target = "textWithNvpms", source = "nullableText") + void update(SafetyGuardSourceBean source, @MappingTarget SafetyGuardTargetBean target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifySafetyGuardTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifySafetyGuardTest.java new file mode 100644 index 0000000000..affff4ad50 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifySafetyGuardTest.java @@ -0,0 +1,68 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Verifies that the pre-existing safety guards in {@code PropertyMapping} (unboxing, + * {@code defaultValue}, {@code NullValuePropertyMappingStrategy.SET_TO_DEFAULT}) still + * generate a null check when the source is {@code @Nullable}. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithClasses({ + SafetyGuardSourceBean.class, + SafetyGuardTargetBean.class, + JSpecifySafetyGuardMapper.class +}) +@WithJSpecify +class JSpecifySafetyGuardTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void nullableSourceToPrimitiveTargetKeepsUnboxingGuard() { + // Source @Nullable Integer is null; unboxing guard must prevent an NPE. + SafetyGuardSourceBean source = new SafetyGuardSourceBean(); + + SafetyGuardTargetBean target = JSpecifySafetyGuardMapper.INSTANCE.map( source ); + + assertThat( target.getUnboxedNumber() ).isZero(); + } + + @ProcessorTest + public void nullableSourceWithDefaultValueKeepsDefaultValueGuard() { + // Source @Nullable String is null; defaultValue must be applied. + SafetyGuardSourceBean source = new SafetyGuardSourceBean(); + + SafetyGuardTargetBean target = JSpecifySafetyGuardMapper.INSTANCE.map( source ); + + assertThat( target.getTextWithDefault() ).isEqualTo( "default" ); + } + + @ProcessorTest + public void nullableSourceWithSetToDefaultKeepsNvpmsGuard() { + // Source @Nullable String is null; NVPMS=SET_TO_DEFAULT must kick in on an update method + // (NVPMS is only honored for update methods) and reset the target to the String default. + SafetyGuardSourceBean source = new SafetyGuardSourceBean(); + SafetyGuardTargetBean target = new SafetyGuardTargetBean(); + target.setTextWithNvpms( "pre-existing" ); + + JSpecifySafetyGuardMapper.INSTANCE.update( source, target ); + + assertThat( target.getTextWithNvpms() ).isEmpty(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyStreamMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyStreamMethodMapper.java new file mode 100644 index 0000000000..1b069af5b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyStreamMethodMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.stream.Stream; + +import org.jspecify.annotations.NullMarked; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@NullMarked +@Mapper +public interface JSpecifyStreamMethodMapper { + + JSpecifyStreamMethodMapper INSTANCE = Mappers.getMapper( JSpecifyStreamMethodMapper.class ); + + Stream mapAll(Stream sources); + + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyStreamMethodTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyStreamMethodTest.java new file mode 100644 index 0000000000..76c7af8792 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyStreamMethodTest.java @@ -0,0 +1,47 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1243") +@WithJSpecify +class JSpecifyStreamMethodTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + @WithClasses({ + NullMarkedSourceBean.class, + NullMarkedTargetBean.class, + JSpecifyStreamMethodMapper.class + }) + void streamMethodWithNonNullSourceSkipsMethodGuard() { + generatedSource.addComparisonToFixtureFor( JSpecifyStreamMethodMapper.class ); + + NullMarkedSourceBean source = new NullMarkedSourceBean(); + source.setNonNullByDefault( "value" ); + + List targets = JSpecifyStreamMethodMapper.INSTANCE + .mapAll( Stream.of( source ) ) + .collect( Collectors.toList() ); + + assertThat( targets ).hasSize( 1 ); + assertThat( targets.get( 0 ).getNonNullByDefault() ).isEqualTo( "value" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyUpdateMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyUpdateMapper.java new file mode 100644 index 0000000000..5eadd23ef1 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyUpdateMapper.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * Mapper with update method and IGNORE strategy to test JSpecify interaction. + * NVPMS=IGNORE means: when source is null, leave target unchanged. + * Source @NonNull should still skip the null check (guaranteed non-null). + */ +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface JSpecifyUpdateMapper { + + JSpecifyUpdateMapper INSTANCE = Mappers.getMapper( JSpecifyUpdateMapper.class ); + + @Mapping(target = "nonNullTarget", source = "nonNullValue") + @Mapping(target = "nullableTarget", source = "nullableValue") + @Mapping(target = "unannotatedTarget", source = "unannotatedValue") + @Mapping(target = "nonNullTargetFromNullable", source = "nullableValue") + void update(SourceBean source, @MappingTarget TargetBean target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyUpdateTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyUpdateTest.java new file mode 100644 index 0000000000..e0e9c24d79 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyUpdateTest.java @@ -0,0 +1,82 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for JSpecify nullness annotations with update methods ({@code @MappingTarget}). + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithClasses({ + SourceBean.class, + TargetBean.class, + JSpecifyUpdateMapper.class +}) +@WithJSpecify +class JSpecifyUpdateTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + public void verifyGeneratedCode() { + generatedSource.addComparisonToFixtureFor( JSpecifyUpdateMapper.class ); + } + + @ProcessorTest + public void sourceNonNullSkipsNullCheckInUpdateMethod() { + // Source @NonNull getter -> no null check, setter always called + SourceBean source = new SourceBean(); + source.setNonNullValue( "updated" ); + + TargetBean target = new TargetBean(); + JSpecifyUpdateMapper.INSTANCE.update( source, target ); + + assertThat( target.isNonNullTargetSet() ).isTrue(); + assertThat( target.getNonNullTarget() ).isEqualTo( "updated" ); + } + + @ProcessorTest + public void sourceNullableWithIgnoreStrategyKeepsNullCheck() { + // Source @Nullable + NVPMS=IGNORE -> null check must be kept (safety guard) + // When source is null, target should be unchanged (IGNORE behavior) + SourceBean source = new SourceBean(); + // nullableValue is null + + TargetBean target = new TargetBean(); + target.setNullableTarget( "original" ); + + JSpecifyUpdateMapper.INSTANCE.update( source, target ); + + // IGNORE strategy: null source should not overwrite -> original value preserved + assertThat( target.getNullableTarget() ).isEqualTo( "original" ); + } + + @ProcessorTest + public void sourceNullableTargetNonNullWithIgnoreStrategyKeepsNullCheck() { + // Source @Nullable + Target @NonNull + NVPMS=IGNORE -> null check kept + SourceBean source = new SourceBean(); + // nullableValue is null + + TargetBean target = new TargetBean(); + target.setNonNullTargetFromNullable( "original" ); + + JSpecifyUpdateMapper.INSTANCE.update( source, target ); + + // null source should not overwrite (IGNORE + null check) + assertThat( target.getNonNullTargetFromNullable() ).isEqualTo( "original" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyVerboseNoteTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyVerboseNoteTest.java new file mode 100644 index 0000000000..46b3d0c869 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/JSpecifyVerboseNoteTest.java @@ -0,0 +1,43 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.WithJSpecify; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedNote; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; +import org.mapstruct.ap.testutil.runner.Compiler; + +/** + * Verifies that JSpecify-driven null-check decisions emit verbose diagnostic notes + * (visible with {@code -Amapstruct.verbose=true}) so they are no longer silent. + * + * @author Filip Hrisafov + */ +@IssueKey("1243") +@WithJSpecify +class JSpecifyVerboseNoteTest { + + @ProcessorTest(Compiler.JDK) + @ProcessorOption(name = "mapstruct.verbose", value = "true") + @WithClasses({ SourceBean.class, TargetBean.class, JSpecifyNullCheckMapper.class }) + @ExpectedNote("^-- MapStruct: JSpecify skipping null check for property \"nonNullTarget\": " + + "source is @NonNull\\.$") + @ExpectedNote("^-- MapStruct: JSpecify adding null check for property \"nonNullTargetFromNullable\": " + + "source=\\w+, target=\\w+\\.$") + public void emitsSetterDecisionNotes() { + } + + @ProcessorTest(Compiler.JDK) + @ProcessorOption(name = "mapstruct.verbose", value = "true") + @WithClasses({ SourceBean.class, TargetBean.class, JSpecifyNonNullParamMapper.class }) + @ExpectedNote("^-- MapStruct: JSpecify skipping method-level null guard for property \"source\": " + + "parameter is @NonNull\\.$") + public void emitsMethodLevelGuardSkipNote() { + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NestedSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NestedSourceBean.java new file mode 100644 index 0000000000..ed67655541 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NestedSourceBean.java @@ -0,0 +1,33 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class NestedSourceBean { + + private AddressBean nonNullAddress; + private AddressBean nullableAddress; + + @NonNull + public AddressBean getNonNullAddress() { + return nonNullAddress; + } + + public void setNonNullAddress(AddressBean nonNullAddress) { + this.nonNullAddress = nonNullAddress; + } + + @Nullable + public AddressBean getNullableAddress() { + return nullableAddress; + } + + public void setNullableAddress(AddressBean nullableAddress) { + this.nullableAddress = nullableAddress; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedCollectionSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedCollectionSourceBean.java new file mode 100644 index 0000000000..3c67457637 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedCollectionSourceBean.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; + +/** + * Source bean with a {@code @NonNull} collection getter (via @NullMarked scope). + */ +@NullMarked +public class NullMarkedCollectionSourceBean { + + private List values; + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedCollectionTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedCollectionTargetBean.java new file mode 100644 index 0000000000..eae3adc1a9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedCollectionTargetBean.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import java.util.List; + +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class NullMarkedCollectionTargetBean { + + private List values; + + public List getValues() { + return values; + } + + public void setValues(List values) { + this.values = values; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedMapper.java new file mode 100644 index 0000000000..e9d45171fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper using @NullMarked source and target beans. + */ +@Mapper +public interface NullMarkedMapper { + + NullMarkedMapper INSTANCE = Mappers.getMapper( NullMarkedMapper.class ); + + @Mapping(target = "nonNullByDefault", source = "nonNullByDefault") + @Mapping(target = "explicitlyNullable", source = "explicitlyNullable") + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedMapperWithParam.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedMapperWithParam.java new file mode 100644 index 0000000000..62e111a143 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedMapperWithParam.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Mapper annotated with @NullMarked. + * Source parameter is effectively @NonNull -> method-level null guard should be skipped. + */ +@NullMarked +@Mapper +public interface NullMarkedMapperWithParam { + + NullMarkedMapperWithParam INSTANCE = Mappers.getMapper( NullMarkedMapperWithParam.class ); + + @Mapping(target = "nonNullByDefault", source = "nonNullByDefault") + @Mapping(target = "explicitlyNullable", source = "explicitlyNullable") + NullMarkedTargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedSourceBean.java new file mode 100644 index 0000000000..d2b1f6a054 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedSourceBean.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * Source bean annotated with {@code @NullMarked}. + * All unannotated types are effectively {@code @NonNull}. + */ +@NullMarked +public class NullMarkedSourceBean { + + private String nonNullByDefault; + private String explicitlyNullable; + + public String getNonNullByDefault() { + return nonNullByDefault; + } + + public void setNonNullByDefault(String nonNullByDefault) { + this.nonNullByDefault = nonNullByDefault; + } + + @Nullable + public String getExplicitlyNullable() { + return explicitlyNullable; + } + + public void setExplicitlyNullable(@Nullable String explicitlyNullable) { + this.explicitlyNullable = explicitlyNullable; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedSourceToPlainTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedSourceToPlainTargetMapper.java new file mode 100644 index 0000000000..de8560d96f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedSourceToPlainTargetMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * Maps from a @NullMarked source to a plain (unannotated) target. + * Source unannotated getters are effectively @NonNull -> skip null check. + * Source @Nullable getter to unannotated target -> defer to strategy. + */ +@Mapper +public interface NullMarkedSourceToPlainTargetMapper { + + NullMarkedSourceToPlainTargetMapper INSTANCE = Mappers.getMapper( NullMarkedSourceToPlainTargetMapper.class ); + + @Mapping(target = "unannotatedTarget", source = "nonNullByDefault") + @Mapping(target = "nullableTarget", source = "explicitlyNullable") + @Mapping(target = "nonNullTarget", ignore = true) + @Mapping(target = "nonNullTargetFromNullable", ignore = true) + TargetBean map(NullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedTargetBean.java new file mode 100644 index 0000000000..a1d0e67893 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullMarkedTargetBean.java @@ -0,0 +1,50 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +/** + * Target bean annotated with {@code @NullMarked}. + * All unannotated setter parameters are effectively {@code @NonNull}. + */ +@NullMarked +public class NullMarkedTargetBean { + + private String nonNullByDefault; + private boolean nonNullByDefaultSet; + + private String explicitlyNullable; + private boolean explicitlyNullableSet; + + public String getNonNullByDefault() { + return nonNullByDefault; + } + + public void setNonNullByDefault(String nonNullByDefault) { + this.nonNullByDefaultSet = true; + this.nonNullByDefault = nonNullByDefault; + } + + public boolean isNonNullByDefaultSet() { + return nonNullByDefaultSet; + } + + @Nullable + public String getExplicitlyNullable() { + return explicitlyNullable; + } + + public void setExplicitlyNullable(@Nullable String explicitlyNullable) { + this.explicitlyNullableSet = true; + this.explicitlyNullable = explicitlyNullable; + } + + public boolean isExplicitlyNullableSet() { + return explicitlyNullableSet; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullUnmarkedSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullUnmarkedSourceBean.java new file mode 100644 index 0000000000..7b3ed11750 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/NullUnmarkedSourceBean.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.NullUnmarked; + +/** + * A {@code @NullMarked} outer class with a {@code @NullUnmarked} nested class. + * The nested class's unannotated getter must have unknown nullability — the closer + * {@code @NullUnmarked} takes precedence over the outer {@code @NullMarked} scope. + */ +@NullMarked +public final class NullUnmarkedSourceBean { + + private NullUnmarkedSourceBean() { + } + + @NullUnmarked + public static class Inner { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SafetyGuardSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SafetyGuardSourceBean.java new file mode 100644 index 0000000000..74bb8d162d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SafetyGuardSourceBean.java @@ -0,0 +1,36 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.Nullable; + +/** + * Source bean for verifying that existing safety guards (unboxing, defaultValue, NVPMS) + * still emit null checks when the source is {@code @Nullable}. + */ +public class SafetyGuardSourceBean { + + private Integer nullableNumber; + private String nullableText; + + @Nullable + public Integer getNullableNumber() { + return nullableNumber; + } + + public void setNullableNumber(@Nullable Integer nullableNumber) { + this.nullableNumber = nullableNumber; + } + + @Nullable + public String getNullableText() { + return nullableText; + } + + public void setNullableText(@Nullable String nullableText) { + this.nullableText = nullableText; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SafetyGuardTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SafetyGuardTargetBean.java new file mode 100644 index 0000000000..e45264bf49 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SafetyGuardTargetBean.java @@ -0,0 +1,37 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +public class SafetyGuardTargetBean { + + private int unboxedNumber; + private String textWithDefault; + private String textWithNvpms; + + public int getUnboxedNumber() { + return unboxedNumber; + } + + public void setUnboxedNumber(int unboxedNumber) { + this.unboxedNumber = unboxedNumber; + } + + public String getTextWithDefault() { + return textWithDefault; + } + + public void setTextWithDefault(String textWithDefault) { + this.textWithDefault = textWithDefault; + } + + public String getTextWithNvpms() { + return textWithNvpms; + } + + public void setTextWithNvpms(String textWithNvpms) { + this.textWithNvpms = textWithNvpms; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SourceBean.java new file mode 100644 index 0000000000..a40806ff6e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/SourceBean.java @@ -0,0 +1,42 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class SourceBean { + + private String nonNullValue; + private String nullableValue; + private String unannotatedValue; + + @NonNull + public String getNonNullValue() { + return nonNullValue; + } + + public void setNonNullValue(String nonNullValue) { + this.nonNullValue = nonNullValue; + } + + @Nullable + public String getNullableValue() { + return nullableValue; + } + + public void setNullableValue(String nullableValue) { + this.nullableValue = nullableValue; + } + + public String getUnannotatedValue() { + return unannotatedValue; + } + + public void setUnannotatedValue(String unannotatedValue) { + this.unannotatedValue = unannotatedValue; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/TargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/TargetBean.java new file mode 100644 index 0000000000..0e87b13eaf --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/TargetBean.java @@ -0,0 +1,76 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; +import org.jspecify.annotations.Nullable; + +public class TargetBean { + + private String nonNullTarget; + private boolean nonNullTargetSet; + + private String nullableTarget; + private boolean nullableTargetSet; + + private String nonNullTargetFromNullable; + private boolean nonNullTargetFromNullableSet; + + private String unannotatedTarget; + private boolean unannotatedTargetSet; + + public String getNonNullTarget() { + return nonNullTarget; + } + + public void setNonNullTarget(@NonNull String nonNullTarget) { + this.nonNullTargetSet = true; + this.nonNullTarget = nonNullTarget; + } + + public boolean isNonNullTargetSet() { + return nonNullTargetSet; + } + + public String getNullableTarget() { + return nullableTarget; + } + + public void setNullableTarget(@Nullable String nullableTarget) { + this.nullableTargetSet = true; + this.nullableTarget = nullableTarget; + } + + public boolean isNullableTargetSet() { + return nullableTargetSet; + } + + public String getNonNullTargetFromNullable() { + return nonNullTargetFromNullable; + } + + public void setNonNullTargetFromNullable(@NonNull String nonNullTargetFromNullable) { + this.nonNullTargetFromNullableSet = true; + this.nonNullTargetFromNullable = nonNullTargetFromNullable; + } + + public boolean isNonNullTargetFromNullableSet() { + return nonNullTargetFromNullableSet; + } + + public String getUnannotatedTarget() { + return unannotatedTarget; + } + + public void setUnannotatedTarget(String unannotatedTarget) { + this.unannotatedTargetSet = true; + this.unannotatedTarget = unannotatedTarget; + } + + public boolean isUnannotatedTargetSet() { + return unannotatedTargetSet; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/UnmappableConstructorTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/UnmappableConstructorTargetBean.java new file mode 100644 index 0000000000..3253e3b390 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/UnmappableConstructorTargetBean.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify; + +import org.jspecify.annotations.NonNull; + +public class UnmappableConstructorTargetBean { + + private final AddressBean payload; + + public UnmappableConstructorTargetBean(@NonNull AddressBean payload) { + this.payload = payload; + } + + public AddressBean getPayload() { + return payload; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedMapper.java new file mode 100644 index 0000000000..f6f72ca243 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedMapper.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage; + +import org.mapstruct.Mapper; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +/** + * Mapper in a @NullMarked package with NullValueCheckStrategy.ALWAYS. + * Since the package is @NullMarked, unannotated types are effectively @NonNull + * and no null checks are produced despite the ALWAYS strategy. + */ +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface PackageNullMarkedMapper { + + PackageNullMarkedMapper INSTANCE = Mappers.getMapper( PackageNullMarkedMapper.class ); + + PackageNullMarkedTargetBean map(PackageNullMarkedSourceBean source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedSourceBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedSourceBean.java new file mode 100644 index 0000000000..8b9deb00f2 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedSourceBean.java @@ -0,0 +1,23 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage; + +/** + * Source bean in a @NullMarked package. + * Unannotated getter is effectively @NonNull. + */ +public class PackageNullMarkedSourceBean { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedTargetBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedTargetBean.java new file mode 100644 index 0000000000..e96af7ad04 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/PackageNullMarkedTargetBean.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage; + +/** + * Target bean in a @NullMarked package. + * Unannotated setter parameter is effectively @NonNull. + */ +public class PackageNullMarkedTargetBean { + + private String value; + private boolean valueSet; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.valueSet = true; + this.value = value; + } + + public boolean isValueSet() { + return valueSet; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/package-info.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/package-info.java new file mode 100644 index 0000000000..ee700639e0 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/jspecify/nullmarkedpackage/package-info.java @@ -0,0 +1,9 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +@NullMarked +package org.mapstruct.ap.test.nullcheck.jspecify.nullmarkedpackage; + +import org.jspecify.annotations.NullMarked; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseDto.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseDto.java new file mode 100644 index 0000000000..141c893373 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseDto.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.strategy; + +public class HouseDto { + + private String owner; + private Integer number; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + this.owner = owner; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + this.number = number; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseEntity.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseEntity.java new file mode 100644 index 0000000000..943a5c3f5a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseEntity.java @@ -0,0 +1,41 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.strategy; + +public class HouseEntity { + + private String owner; + private boolean ownerSet = false; + + private Integer number; + private boolean numberSet = false; + + public String getOwner() { + return owner; + } + + public void setOwner(String owner) { + ownerSet = true; + this.owner = owner; + } + + public boolean ownerSet() { + return ownerSet; + } + + public Integer getNumber() { + return number; + } + + public void setNumber(Integer number) { + numberSet = true; + this.number = number; + } + + public boolean numberSet() { + return numberSet; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapper.java new file mode 100644 index 0000000000..860fbc6579 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.strategy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) +public interface HouseMapper { + + HouseMapper INSTANCE = Mappers.getMapper( HouseMapper.class ); + + HouseEntity mapWithNvcsOnMapper(HouseDto in); + + @BeanMapping(nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION) + HouseEntity mapWithNvcsOnBean(HouseDto in); + + @BeanMapping(nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION) + @Mapping(target = "number", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) + HouseEntity mapWithNvcsOnMapping(HouseDto in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapperConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapperConfig.java new file mode 100644 index 0000000000..24753bb8dc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapperConfig.java @@ -0,0 +1,15 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.strategy; + +import org.mapstruct.MapperConfig; +import org.mapstruct.NullValueCheckStrategy; + +@MapperConfig( + nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS +) +public interface HouseMapperConfig { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapperWithConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapperWithConfig.java new file mode 100644 index 0000000000..ceb703fdfe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/HouseMapperWithConfig.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.strategy; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueCheckStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(config = HouseMapperConfig.class) +public interface HouseMapperWithConfig { + + HouseMapperWithConfig INSTANCE = Mappers.getMapper( HouseMapperWithConfig.class ); + + HouseEntity mapWithNvcsOnMapper(HouseDto in); + + @BeanMapping(nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION) + HouseEntity mapWithNvcsOnBean(HouseDto in); + + @BeanMapping(nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION) + @Mapping(target = "number", nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS) + HouseEntity mapWithNvcsOnMapping(HouseDto in); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/NullValueCheckTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/NullValueCheckTest.java new file mode 100644 index 0000000000..256d3f7d92 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullcheck/strategy/NullValueCheckTest.java @@ -0,0 +1,90 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullcheck.strategy; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey("1571") +@WithClasses({ + HouseDto.class, + HouseEntity.class, + HouseMapper.class, + HouseMapperConfig.class, + HouseMapperWithConfig.class +}) +public class NullValueCheckTest { + + @ProcessorTest + public void testDefinedOnMapper() { + + HouseEntity entity = HouseMapper.INSTANCE.mapWithNvcsOnMapper( new HouseDto() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.ownerSet() ).isFalse(); + assertThat( entity.numberSet() ).isFalse(); + + } + + @ProcessorTest + public void testDefinedOnBean() { + + HouseEntity entity = HouseMapper.INSTANCE.mapWithNvcsOnBean( new HouseDto() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.ownerSet() ).isTrue(); + assertThat( entity.numberSet() ).isTrue(); + + } + + @ProcessorTest + public void testDefinedOnMapping() { + + HouseEntity entity = HouseMapper.INSTANCE.mapWithNvcsOnMapping( new HouseDto() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.ownerSet() ).isTrue(); + assertThat( entity.numberSet() ).isFalse(); + + } + + @ProcessorTest + public void testDefinedOnConfig() { + + HouseEntity entity = HouseMapperWithConfig.INSTANCE.mapWithNvcsOnMapper( new HouseDto() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.ownerSet() ).isFalse(); + assertThat( entity.numberSet() ).isFalse(); + + } + + @ProcessorTest + public void testDefinedOnConfigAndBean() { + + HouseEntity entity = HouseMapperWithConfig.INSTANCE.mapWithNvcsOnBean( new HouseDto() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.ownerSet() ).isTrue(); + assertThat( entity.numberSet() ).isTrue(); + + } + + @ProcessorTest + public void testDefinedOnConfigAndMapping() { + + HouseEntity entity = HouseMapperWithConfig.INSTANCE.mapWithNvcsOnMapping( new HouseDto() ); + + assertThat( entity ).isNotNull(); + assertThat( entity.ownerSet() ).isTrue(); + assertThat( entity.numberSet() ).isFalse(); + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarListMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarListMapper.java new file mode 100644 index 0000000000..d239f9ace7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarListMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CarListMapper { + + CarListMapper INSTANCE = Mappers.getMapper( CarListMapper.class ); + + @Mapping(target = "seatCount", ignore = true) + @Mapping(target = "model", ignore = true) + @Mapping(target = "catalogId", ignore = true) + CarDto map(Car car); + + List carsToCarDtoList(List cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarListMapperSettingOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarListMapperSettingOnMapper.java new file mode 100644 index 0000000000..860b17654a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarListMapperSettingOnMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.List; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(nullValueIterableMappingStrategy = NullValueMappingStrategy.RETURN_NULL) +public interface CarListMapperSettingOnMapper { + + CarListMapperSettingOnMapper INSTANCE = Mappers.getMapper( CarListMapperSettingOnMapper.class ); + + @Mapping(target = "seatCount", ignore = true) + @Mapping(target = "model", ignore = true) + @Mapping(target = "catalogId", ignore = true) + CarDto map(Car car); + + List carsToCarDtoList(List cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapMapper.java new file mode 100644 index 0000000000..0227949f4d --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapMapper.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface CarMapMapper { + + CarMapMapper INSTANCE = Mappers.getMapper( CarMapMapper.class ); + + @Mapping(target = "seatCount", ignore = true) + @Mapping(target = "model", ignore = true) + @Mapping(target = "catalogId", ignore = true) + CarDto map(Car car); + + Map carsToCarDtoMap(Map cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapMapperSettingOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapMapperSettingOnMapper.java new file mode 100644 index 0000000000..adb99887bd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapMapperSettingOnMapper.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.Map; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(nullValueMapMappingStrategy = NullValueMappingStrategy.RETURN_NULL) +public interface CarMapMapperSettingOnMapper { + + CarMapMapperSettingOnMapper INSTANCE = Mappers.getMapper( CarMapMapperSettingOnMapper.class ); + + @Mapping(target = "seatCount", ignore = true) + @Mapping(target = "model", ignore = true) + @Mapping(target = "catalogId", ignore = true) + CarDto map(Car car); + + Map carsToCarDtoMap(Map cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapper.java index c6f8ae5182..53f9e39cbd 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapper.java @@ -1,25 +1,10 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping; -import static org.mapstruct.NullValueMappingStrategy.RETURN_DEFAULT; - import java.util.List; import java.util.Map; import java.util.UUID; @@ -29,32 +14,28 @@ import org.mapstruct.MapMapping; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; import org.mapstruct.ap.test.nullvaluemapping._target.DriverAndCarDto; import org.mapstruct.ap.test.nullvaluemapping.source.Car; import org.mapstruct.ap.test.nullvaluemapping.source.Driver; import org.mapstruct.factory.Mappers; +import static org.mapstruct.NullValueMappingStrategy.RETURN_DEFAULT; + @Mapper(imports = UUID.class) public interface CarMapper { CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); @BeanMapping(nullValueMappingStrategy = RETURN_DEFAULT) - @Mappings({ - @Mapping(target = "seatCount", source = "numberOfSeats"), - @Mapping(target = "model", constant = "ModelT"), - @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") - }) + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") CarDto carToCarDto(Car car); @BeanMapping(nullValueMappingStrategy = RETURN_DEFAULT) - @Mappings({ - @Mapping(target = "seatCount", source = "car.numberOfSeats"), - @Mapping(target = "model", source = "model"), // TODO, should not be needed, must be made based on name only - @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") - }) + @Mapping(target = "seatCount", source = "car.numberOfSeats") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") CarDto carToCarDto(Car car, String model); @IterableMapping(nullValueMappingStrategy = RETURN_DEFAULT) diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperIterableSettingOnConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperIterableSettingOnConfig.java new file mode 100644 index 0000000000..8fd9447073 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperIterableSettingOnConfig.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.mapstruct.IterableMapping; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +@Mapper(imports = UUID.class, config = CentralIterableMappingConfig.class) +public interface CarMapperIterableSettingOnConfig { + + CarMapperIterableSettingOnConfig INSTANCE = Mappers.getMapper( CarMapperIterableSettingOnConfig.class ); + + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") + CarDto carToCarDto(Car car); + + @IterableMapping(dateFormat = "dummy") + List carsToCarDtos(List cars); + + @MapMapping(valueDateFormat = "dummy") + Map carsToCarDtoMap(Map cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperIterableSettingOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperIterableSettingOnMapper.java new file mode 100644 index 0000000000..0e1e123c52 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperIterableSettingOnMapper.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.mapstruct.IterableMapping; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +@Mapper( + imports = UUID.class, + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueIterableMappingStrategy = NullValueMappingStrategy.RETURN_NULL +) +public interface CarMapperIterableSettingOnMapper { + + CarMapperIterableSettingOnMapper INSTANCE = Mappers.getMapper( CarMapperIterableSettingOnMapper.class ); + + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") + CarDto carToCarDto(Car car); + + @IterableMapping(dateFormat = "dummy") + List carsToCarDtos(List cars); + + @MapMapping(valueDateFormat = "dummy") + Map carsToCarDtoMap(Map cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperMapSettingOnConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperMapSettingOnConfig.java new file mode 100644 index 0000000000..47f0f34f63 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperMapSettingOnConfig.java @@ -0,0 +1,35 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.mapstruct.IterableMapping; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +@Mapper(imports = UUID.class, config = CentralMapMappingConfig.class) +public interface CarMapperMapSettingOnConfig { + + CarMapperMapSettingOnConfig INSTANCE = Mappers.getMapper( CarMapperMapSettingOnConfig.class ); + + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") + CarDto carToCarDto(Car car); + + @IterableMapping(dateFormat = "dummy") + List carsToCarDtos(List cars); + + @MapMapping(valueDateFormat = "dummy") + Map carsToCarDtoMap(Map cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperMapSettingOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperMapSettingOnMapper.java new file mode 100644 index 0000000000..0caad062c5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperMapSettingOnMapper.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.mapstruct.IterableMapping; +import org.mapstruct.MapMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.NullValueMappingStrategy; +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.factory.Mappers; + +@Mapper( + imports = UUID.class, + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueMapMappingStrategy = NullValueMappingStrategy.RETURN_NULL +) +public interface CarMapperMapSettingOnMapper { + + CarMapperMapSettingOnMapper INSTANCE = Mappers.getMapper( CarMapperMapSettingOnMapper.class ); + + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") + CarDto carToCarDto(Car car); + + @IterableMapping(dateFormat = "dummy") + List carsToCarDtos(List cars); + + @MapMapping(valueDateFormat = "dummy") + Map carsToCarDtoMap(Map cars); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnConfig.java index bdfacf29b3..8e4ca2dac6 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping; @@ -26,7 +13,6 @@ import org.mapstruct.MapMapping; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.NullValueMappingStrategy; import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; import org.mapstruct.ap.test.nullvaluemapping.source.Car; @@ -37,11 +23,9 @@ public interface CarMapperSettingOnConfig { CarMapperSettingOnConfig INSTANCE = Mappers.getMapper( CarMapperSettingOnConfig.class ); - @Mappings({ - @Mapping(target = "seatCount", source = "numberOfSeats"), - @Mapping(target = "model", constant = "ModelT"), - @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") - }) + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") CarDto carToCarDto(Car car); @IterableMapping(dateFormat = "dummy") diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnMapper.java index 32e56d8cba..2306b3add4 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CarMapperSettingOnMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping; @@ -26,7 +13,6 @@ import org.mapstruct.MapMapping; import org.mapstruct.Mapper; import org.mapstruct.Mapping; -import org.mapstruct.Mappings; import org.mapstruct.NullValueMappingStrategy; import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; import org.mapstruct.ap.test.nullvaluemapping.source.Car; @@ -37,11 +23,9 @@ public interface CarMapperSettingOnMapper { CarMapperSettingOnMapper INSTANCE = Mappers.getMapper( CarMapperSettingOnMapper.class ); - @Mappings({ - @Mapping(target = "seatCount", source = "numberOfSeats"), - @Mapping(target = "model", constant = "ModelT"), - @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") - }) + @Mapping(target = "seatCount", source = "numberOfSeats") + @Mapping(target = "model", constant = "ModelT") + @Mapping(target = "catalogId", expression = "java( UUID.randomUUID().toString() )") CarDto carToCarDto(Car car); @IterableMapping(nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT) diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralConfig.java index a876ce66a6..5a39f55f51 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralConfig.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralConfig.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 +/* + * Copyright MapStruct Authors. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralIterableMappingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralIterableMappingConfig.java new file mode 100644 index 0000000000..559c3520a9 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralIterableMappingConfig.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import org.mapstruct.MapperConfig; +import org.mapstruct.NullValueMappingStrategy; + +@MapperConfig( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueIterableMappingStrategy = NullValueMappingStrategy.RETURN_NULL +) +public class CentralIterableMappingConfig { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralMapMappingConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralMapMappingConfig.java new file mode 100644 index 0000000000..7737e07de6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/CentralMapMappingConfig.java @@ -0,0 +1,17 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import org.mapstruct.MapperConfig; +import org.mapstruct.NullValueMappingStrategy; + +@MapperConfig( + nullValueMappingStrategy = NullValueMappingStrategy.RETURN_DEFAULT, + nullValueMapMappingStrategy = NullValueMappingStrategy.RETURN_NULL +) +public class CentralMapMappingConfig { + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueIterableMappingStrategyTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueIterableMappingStrategyTest.java new file mode 100644 index 0000000000..c4acecd64f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueIterableMappingStrategyTest.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + CarDto.class, + Car.class +}) +@IssueKey("2953") +public class NullValueIterableMappingStrategyTest { + + @ProcessorTest + @ProcessorOption(name = "mapstruct.nullValueIterableMappingStrategy", value = "return_default") + @WithClasses({ + CarListMapper.class + }) + void globalNullIterableMappingStrategy() { + assertThat( CarListMapper.INSTANCE.carsToCarDtoList( null ) ).isEmpty(); + } + + @ProcessorTest + @ProcessorOption(name = "mapstruct.nullValueIterableMappingStrategy", value = "return_default") + @WithClasses({ + CarListMapperSettingOnMapper.class + }) + void globalNullMapMappingStrategyWithOverrideInMapper() { + // Explicit definition in @Mapper should override global + assertThat( CarListMapperSettingOnMapper.INSTANCE.carsToCarDtoList( null ) ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMapMappingStrategyTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMapMappingStrategyTest.java new file mode 100644 index 0000000000..33b5942f85 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMapMappingStrategyTest.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluemapping; + +import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; +import org.mapstruct.ap.test.nullvaluemapping.source.Car; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + CarDto.class, + Car.class +}) +@IssueKey("2953") +public class NullValueMapMappingStrategyTest { + + @ProcessorTest + @ProcessorOption(name = "mapstruct.nullValueMapMappingStrategy", value = "return_default") + @WithClasses({ + CarMapMapper.class + }) + void globalNullMapMappingStrategy() { + assertThat( CarMapMapper.INSTANCE.carsToCarDtoMap( null ) ).isEmpty(); + } + + @ProcessorTest + @ProcessorOption(name = "mapstruct.nullValueMapMappingStrategy", value = "return_default") + @WithClasses({ + CarMapMapperSettingOnMapper.class + }) + void globalNullMapMappingStrategyWithOverrideInMapper() { + // Explicit definition in @Mapper should override global + assertThat( CarMapMapperSettingOnMapper.INSTANCE.carsToCarDtoMap( null ) ).isNull(); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMappingTest.java index bc825f001e..a027acaba3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMappingTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/NullValueMappingTest.java @@ -1,39 +1,24 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping; -import static org.assertj.core.api.Assertions.assertThat; - import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.test.nullvaluemapping._target.CarDto; import org.mapstruct.ap.test.nullvaluemapping._target.DriverAndCarDto; import org.mapstruct.ap.test.nullvaluemapping.source.Car; import org.mapstruct.ap.test.nullvaluemapping.source.Driver; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests for the strategies for mapping {@code null} values, given via {@code NullValueMapping} etc. @@ -48,18 +33,23 @@ DriverAndCarDto.class, CarMapper.class, CarMapperSettingOnMapper.class, + CarMapperIterableSettingOnMapper.class, + CarMapperMapSettingOnMapper.class, CentralConfig.class, - CarMapperSettingOnConfig.class + CarMapperSettingOnConfig.class, + CentralIterableMappingConfig.class, + CarMapperIterableSettingOnConfig.class, + CentralMapMappingConfig.class, + CarMapperMapSettingOnConfig.class, }) -@RunWith(AnnotationProcessorTestRunner.class) public class NullValueMappingTest { - @Test - public void shouldProvideMapperInstance() throws Exception { + @ProcessorTest + public void shouldProvideMapperInstance() { assertThat( CarMapper.INSTANCE ).isNotNull(); } - @Test + @ProcessorTest public void shouldMapExpressionAndConstantRegardlessNullArg() { //given Car car = new Car( "Morris", 2 ); @@ -85,7 +75,7 @@ public void shouldMapExpressionAndConstantRegardlessNullArg() { assertThat( carDto2.getCatalogId() ).isNotEmpty(); } - @Test + @ProcessorTest public void shouldMapExpressionAndConstantRegardlessNullArgSeveralSources() { //given Car car = new Car( "Morris", 2 ); @@ -96,6 +86,7 @@ public void shouldMapExpressionAndConstantRegardlessNullArgSeveralSources() { //then assertThat( carDto1 ).isNotNull(); assertThat( carDto1.getMake() ).isEqualTo( car.getMake() ); + assertThat( carDto1.getModel() ).isEqualTo( "ModelT" ); assertThat( carDto1.getSeatCount() ).isEqualTo( car.getNumberOfSeats() ); assertThat( carDto1.getCatalogId() ).isNotEmpty(); @@ -110,7 +101,7 @@ public void shouldMapExpressionAndConstantRegardlessNullArgSeveralSources() { assertThat( carDto2.getCatalogId() ).isNotEmpty(); } - @Test + @ProcessorTest public void shouldMapIterableWithNullArg() { //given @@ -131,7 +122,7 @@ public void shouldMapIterableWithNullArg() { assertThat( carDtos2.isEmpty() ).isTrue(); } - @Test + @ProcessorTest @SuppressWarnings({ "rawtypes", "unchecked" }) public void shouldMapMapWithNullArg() { @@ -155,7 +146,7 @@ public void shouldMapMapWithNullArg() { assertThat( carDtoMap2.isEmpty() ).isTrue(); } - @Test + @ProcessorTest public void shouldMapExpressionAndConstantRegardlessNullArgOnMapper() { //when @@ -169,18 +160,17 @@ public void shouldMapExpressionAndConstantRegardlessNullArgOnMapper() { assertThat( carDto.getCatalogId() ).isNotEmpty(); } - @Test + @ProcessorTest public void shouldMapIterableWithNullArgOnMapper() { //when List carDtos = CarMapperSettingOnMapper.INSTANCE.carsToCarDtos( null ); //then - assertThat( carDtos ).isNotNull(); - assertThat( carDtos.isEmpty() ).isTrue(); + assertThat( carDtos ).isEmpty(); } - @Test + @ProcessorTest public void shouldMapMapWithNullArgOnMapper() { //when @@ -190,7 +180,75 @@ public void shouldMapMapWithNullArgOnMapper() { assertThat( carDtoMap ).isNull(); } - @Test + @ProcessorTest + public void shouldMapExpressionAndConstantRegardlessOfIterableNullArgOnMapper() { + + //when + CarDto carDto = CarMapperIterableSettingOnMapper.INSTANCE.carToCarDto( null ); + + //then + assertThat( carDto ).isNotNull(); + assertThat( carDto.getMake() ).isNull(); + assertThat( carDto.getSeatCount() ).isEqualTo( 0 ); + assertThat( carDto.getModel() ).isEqualTo( "ModelT" ); + assertThat( carDto.getCatalogId() ).isNotEmpty(); + } + + @ProcessorTest + public void shouldMapIterableToNullWithIterableNullArgOnMapper() { + + //when + List carDtos = CarMapperIterableSettingOnMapper.INSTANCE.carsToCarDtos( null ); + + //then + assertThat( carDtos ).isNull(); + } + + @ProcessorTest + public void shouldMapMapRegardlessOfIterableNullArgOnMapper() { + + //when + Map carDtoMap = CarMapperIterableSettingOnMapper.INSTANCE.carsToCarDtoMap( null ); + + //then + assertThat( carDtoMap ).isEmpty(); + } + + @ProcessorTest + public void shouldMapExpressionAndConstantRegardlessMapNullArgOnMapper() { + + //when + CarDto carDto = CarMapperMapSettingOnMapper.INSTANCE.carToCarDto( null ); + + //then + assertThat( carDto ).isNotNull(); + assertThat( carDto.getMake() ).isNull(); + assertThat( carDto.getSeatCount() ).isEqualTo( 0 ); + assertThat( carDto.getModel() ).isEqualTo( "ModelT" ); + assertThat( carDto.getCatalogId() ).isNotEmpty(); + } + + @ProcessorTest + public void shouldMapIterableRegardlessOfMapNullArgOnMapper() { + + //when + List carDtos = CarMapperMapSettingOnMapper.INSTANCE.carsToCarDtos( null ); + + //then + assertThat( carDtos ).isEmpty(); + } + + @ProcessorTest + public void shouldMapMapToWithMapNullArgOnMapper() { + + //when + Map carDtoMap = CarMapperMapSettingOnMapper.INSTANCE.carsToCarDtoMap( null ); + + //then + assertThat( carDtoMap ).isNull(); + } + + @ProcessorTest public void shouldMapExpressionAndConstantRegardlessNullArgOnConfig() { //when @@ -204,18 +262,17 @@ public void shouldMapExpressionAndConstantRegardlessNullArgOnConfig() { assertThat( carDto.getCatalogId() ).isNotEmpty(); } - @Test + @ProcessorTest public void shouldMapIterableWithNullArgOnConfig() { //when List carDtos = CarMapperSettingOnConfig.INSTANCE.carsToCarDtos( null ); //then - assertThat( carDtos ).isNotNull(); - assertThat( carDtos.isEmpty() ).isTrue(); + assertThat( carDtos ).isEmpty(); } - @Test + @ProcessorTest public void shouldMapMapWithNullArgOnConfig() { //when @@ -225,7 +282,75 @@ public void shouldMapMapWithNullArgOnConfig() { assertThat( carDtoMap ).isNull(); } - @Test + @ProcessorTest + public void shouldMapExpressionAndConstantRegardlessOfIterableNullArgOnConfig() { + + //when + CarDto carDto = CarMapperIterableSettingOnConfig.INSTANCE.carToCarDto( null ); + + //then + assertThat( carDto ).isNotNull(); + assertThat( carDto.getMake() ).isNull(); + assertThat( carDto.getSeatCount() ).isEqualTo( 0 ); + assertThat( carDto.getModel() ).isEqualTo( "ModelT" ); + assertThat( carDto.getCatalogId() ).isNotEmpty(); + } + + @ProcessorTest + public void shouldMapIterableToNullWithIterableNullArgOnConfig() { + + //when + List carDtos = CarMapperIterableSettingOnConfig.INSTANCE.carsToCarDtos( null ); + + //then + assertThat( carDtos ).isNull(); + } + + @ProcessorTest + public void shouldMapMapRegardlessOfIterableNullArgOnConfig() { + + //when + Map carDtoMap = CarMapperIterableSettingOnConfig.INSTANCE.carsToCarDtoMap( null ); + + //then + assertThat( carDtoMap ).isEmpty(); + } + + @ProcessorTest + public void shouldMapExpressionAndConstantRegardlessOfMapNullArgOnConfig() { + + //when + CarDto carDto = CarMapperMapSettingOnConfig.INSTANCE.carToCarDto( null ); + + //then + assertThat( carDto ).isNotNull(); + assertThat( carDto.getMake() ).isNull(); + assertThat( carDto.getSeatCount() ).isEqualTo( 0 ); + assertThat( carDto.getModel() ).isEqualTo( "ModelT" ); + assertThat( carDto.getCatalogId() ).isNotEmpty(); + } + + @ProcessorTest + public void shouldMapIterableRegardlessOfMapNullArgOnConfig() { + + //when + List carDtos = CarMapperMapSettingOnConfig.INSTANCE.carsToCarDtos( null ); + + //then + assertThat( carDtos ).isEmpty(); + } + + @ProcessorTest + public void shouldMapMapToNullWithMapNullArgOnConfig() { + + //when + Map carDtoMap = CarMapperMapSettingOnConfig.INSTANCE.carsToCarDtoMap( null ); + + //then + assertThat( carDtoMap ).isNull(); + } + + @ProcessorTest public void shouldApplyConfiguredStrategyForMethodWithSeveralSourceParams() { //when DriverAndCarDto result = CarMapper.INSTANCE.driverAndCarToDto( null, null ); diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/CarDto.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/CarDto.java index aa18e39301..dca67b4d5e 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/CarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/CarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/DriverAndCarDto.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/DriverAndCarDto.java index c2def9d265..10af703211 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/DriverAndCarDto.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/_target/DriverAndCarDto.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping._target; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Car.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Car.java index 70d63a7b01..f0ca97b7a7 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Car.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Car.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Driver.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Driver.java index 93afa27ae6..89322fd4a8 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Driver.java +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluemapping/source/Driver.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.nullvaluemapping.source; diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/Address.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/Address.java new file mode 100644 index 0000000000..86c76f4d50 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/Address.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +public class Address { + + private Integer houseNumber; + + public Integer getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber(Integer houseNumber) { + this.houseNumber = houseNumber; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/AddressDTO.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/AddressDTO.java new file mode 100644 index 0000000000..3fca3b046f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/AddressDTO.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +public class AddressDTO { + + private Integer houseNo; + + public Integer getHouseNo() { + return houseNo; + } + + public void setHouseNo(Integer houseNo) { + this.houseNo = houseNo; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/Customer.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/Customer.java new file mode 100644 index 0000000000..ac750aeb5a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/Customer.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import java.util.List; + +public class Customer { + + private Address address; + private List details; + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDTO.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDTO.java new file mode 100644 index 0000000000..b2475cd4c7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDTO.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import java.util.List; + +public class CustomerDTO { + + private AddressDTO address; + private List details; + + public AddressDTO getAddress() { + return address; + } + + public void setAddress(AddressDTO address) { + this.address = address; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java new file mode 100644 index 0000000000..1f95649dd8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerDefaultMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.SET_TO_DEFAULT) +public interface CustomerDefaultMapper { + + CustomerDefaultMapper INSTANCE = Mappers.getMapper( CustomerDefaultMapper.class ); + + @Mapping(target = "homeDTO.addressDTO", source = "address") + void mapCustomer(Customer customer, @MappingTarget UserDTO userDTO); + + @Mapping(target = "houseNo", defaultValue = "0", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerMapper.java new file mode 100644 index 0000000000..339f70516b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerMapper.java @@ -0,0 +1,26 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface CustomerMapper { + + CustomerMapper INSTANCE = Mappers.getMapper( CustomerMapper.class ); + + @Mapping(target = "homeDTO.addressDTO", source = "address") + void mapCustomer(Customer customer, @MappingTarget UserDTO userDTO); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnBeanMappingMethodMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnBeanMappingMethodMapper.java new file mode 100644 index 0000000000..85a685b943 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnBeanMappingMethodMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CustomerNvpmsOnBeanMappingMethodMapper { + + CustomerNvpmsOnBeanMappingMethodMapper INSTANCE = Mappers.getMapper( CustomerNvpmsOnBeanMappingMethodMapper.class ); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnConfigMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnConfigMapper.java new file mode 100644 index 0000000000..7693c2c969 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnConfigMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +@Mapper(config = NvpmsConfig.class) +public interface CustomerNvpmsOnConfigMapper { + + CustomerNvpmsOnConfigMapper INSTANCE = Mappers.getMapper( CustomerNvpmsOnConfigMapper.class ); + + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnMapperMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnMapperMapper.java new file mode 100644 index 0000000000..1b65c6d5fc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsOnMapperMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +public interface CustomerNvpmsOnMapperMapper { + + CustomerNvpmsOnMapperMapper INSTANCE = Mappers.getMapper( CustomerNvpmsOnMapperMapper.class ); + + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsPropertyMappingMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsPropertyMappingMapper.java new file mode 100644 index 0000000000..a6b3b021fa --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/CustomerNvpmsPropertyMappingMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@Mapper +public interface CustomerNvpmsPropertyMappingMapper { + + CustomerNvpmsPropertyMappingMapper INSTANCE = Mappers.getMapper( CustomerNvpmsPropertyMappingMapper.class ); + + @Mapping( target = "address", nullValuePropertyMappingStrategy = IGNORE) + @Mapping( target = "details", nullValuePropertyMappingStrategy = IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper1.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper1.java new file mode 100644 index 0000000000..e025cfd86c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper1.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@Mapper +public interface ErroneousCustomerMapper1 { + + ErroneousCustomerMapper1 INSTANCE = Mappers.getMapper( ErroneousCustomerMapper1.class ); + + @Mapping(target = "details", defaultValue = "test", nullValuePropertyMappingStrategy = IGNORE) + @Mapping(target = "address", nullValuePropertyMappingStrategy = IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper2.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper2.java new file mode 100644 index 0000000000..fad47afb27 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper2.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@Mapper +public interface ErroneousCustomerMapper2 { + + ErroneousCustomerMapper2 INSTANCE = Mappers.getMapper( ErroneousCustomerMapper2.class ); + + @Mapping(target = "details", expression = "java(getTest())", nullValuePropertyMappingStrategy = IGNORE) + @Mapping(target = "address", nullValuePropertyMappingStrategy = IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper3.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper3.java new file mode 100644 index 0000000000..1a0eae5f4f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper3.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@Mapper +public interface ErroneousCustomerMapper3 { + + ErroneousCustomerMapper3 INSTANCE = Mappers.getMapper( ErroneousCustomerMapper3.class ); + + @Mapping(target = "details", defaultExpression = "java(getTest())", nullValuePropertyMappingStrategy = IGNORE) + @Mapping(target = "address", nullValuePropertyMappingStrategy = IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper4.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper4.java new file mode 100644 index 0000000000..da54f8c9b5 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper4.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@Mapper +public interface ErroneousCustomerMapper4 { + + ErroneousCustomerMapper4 INSTANCE = Mappers.getMapper( ErroneousCustomerMapper4.class ); + + @Mapping(target = "details", constant = "test", nullValuePropertyMappingStrategy = IGNORE) + @Mapping(target = "address", nullValuePropertyMappingStrategy = IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper5.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper5.java new file mode 100644 index 0000000000..fc2861bc15 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/ErroneousCustomerMapper5.java @@ -0,0 +1,28 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.factory.Mappers; + +import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE; + +@Mapper +public interface ErroneousCustomerMapper5 { + + ErroneousCustomerMapper5 INSTANCE = Mappers.getMapper( ErroneousCustomerMapper5.class ); + + @Mapping(target = "details", ignore = true, nullValuePropertyMappingStrategy = IGNORE) + @Mapping(target = "address", nullValuePropertyMappingStrategy = IGNORE) + void map(Customer customer, @MappingTarget CustomerDTO mappingTarget); + + @Mapping(target = "houseNo", source = "houseNumber") + void mapCustomerHouse(Address address, @MappingTarget AddressDTO addrDTO); + +} + diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/HomeDTO.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/HomeDTO.java new file mode 100644 index 0000000000..ad283e5efd --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/HomeDTO.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +public class HomeDTO { + + private AddressDTO addressDTO; + + public AddressDTO getAddressDTO() { + return addressDTO; + } + + public void setAddressDTO(AddressDTO addressDTO) { + this.addressDTO = addressDTO; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/NullValuePropertyMappingTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/NullValuePropertyMappingTest.java new file mode 100644 index 0000000000..dfe2e14d6f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/NullValuePropertyMappingTest.java @@ -0,0 +1,199 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import java.util.Arrays; +import java.util.function.BiConsumer; + +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; +import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; +import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Sjaak Derksen + */ +@IssueKey("1306") +@WithClasses({ + Address.class, + Customer.class, + CustomerDTO.class, + AddressDTO.class, + HomeDTO.class, + UserDTO.class +}) +public class NullValuePropertyMappingTest { + + @ProcessorTest + @WithClasses(CustomerMapper.class) + public void testStrategyAppliedOnForgedMethod() { + + Customer customer = new Customer(); + customer.setAddress( null ); + + UserDTO userDTO = new UserDTO(); + userDTO.setHomeDTO( new HomeDTO() ); + userDTO.getHomeDTO().setAddressDTO( new AddressDTO() ); + userDTO.getHomeDTO().getAddressDTO().setHouseNo( 5 ); + userDTO.setDetails( Arrays.asList( "green hair" ) ); + + CustomerMapper.INSTANCE.mapCustomer( customer, userDTO ); + + assertThat( userDTO.getHomeDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO().getHouseNo() ).isEqualTo( 5 ); + assertThat( userDTO.getDetails() ).isNotNull(); + assertThat( userDTO.getDetails() ).containsExactly( "green hair" ); + } + + @ProcessorTest + @WithClasses({ NvpmsConfig.class, CustomerNvpmsOnConfigMapper.class }) + public void testHierarchyIgnoreOnConfig() { + testConfig( CustomerNvpmsOnConfigMapper.INSTANCE::map ); + } + + @ProcessorTest + @WithClasses(CustomerNvpmsOnMapperMapper.class) + public void testHierarchyIgnoreOnMapping() { + testConfig( CustomerNvpmsOnMapperMapper.INSTANCE::map ); + } + + @ProcessorTest + @WithClasses(CustomerNvpmsOnBeanMappingMethodMapper.class) + public void testHierarchyIgnoreOnBeanMappingMethod() { + testConfig( CustomerNvpmsOnBeanMappingMethodMapper.INSTANCE::map ); + } + + @ProcessorTest + @WithClasses(CustomerNvpmsPropertyMappingMapper.class) + public void testHierarchyIgnoreOnPropertyMappingMethod() { + testConfig( CustomerNvpmsPropertyMappingMapper.INSTANCE::map ); + } + + @ProcessorTest + @WithClasses(CustomerDefaultMapper.class) + public void testStrategyDefaultAppliedOnForgedMethod() { + + Customer customer = new Customer(); + customer.setAddress( null ); + + UserDTO userDTO = new UserDTO(); + userDTO.setHomeDTO( new HomeDTO() ); + userDTO.getHomeDTO().setAddressDTO( new AddressDTO() ); + userDTO.getHomeDTO().getAddressDTO().setHouseNo( 5 ); + userDTO.setDetails( Arrays.asList( "green hair" ) ); + + CustomerDefaultMapper.INSTANCE.mapCustomer( customer, userDTO ); + + assertThat( userDTO.getHomeDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO() ).isNotNull(); + assertThat( userDTO.getHomeDTO().getAddressDTO().getHouseNo() ).isNull(); + assertThat( userDTO.getDetails() ).isNotNull(); + assertThat( userDTO.getDetails() ).isEmpty(); + } + + @ProcessorTest + @WithClasses(ErroneousCustomerMapper1.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCustomerMapper1.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + alternativeLine = 22, // Javac wrong error reporting on repeatable annotations JDK-8042710 + message = "Default value and nullValuePropertyMappingStrategy are both defined in @Mapping, " + + "either define a defaultValue or an nullValuePropertyMappingStrategy.") + } + ) + public void testBothDefaultValueAndNvpmsDefined() { + } + + @ProcessorTest + @WithClasses(ErroneousCustomerMapper2.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCustomerMapper2.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + alternativeLine = 22, // Javac wrong error reporting on repeatable annotations JDK-8042710 + message = "Expression and nullValuePropertyMappingStrategy are both defined in @Mapping, " + + "either define an expression or an nullValuePropertyMappingStrategy.") + } + ) + public void testBothExpressionAndNvpmsDefined() { + } + + @ProcessorTest + @WithClasses(ErroneousCustomerMapper3.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCustomerMapper3.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + alternativeLine = 22, // Javac wrong error reporting on repeatable annotations JDK-8042710 + message = "DefaultExpression and nullValuePropertyMappingStrategy are both defined in " + + "@Mapping, either define a defaultExpression or an nullValuePropertyMappingStrategy.") + } + ) + public void testBothDefaultExpressionAndNvpmsDefined() { + } + + @ProcessorTest + @WithClasses(ErroneousCustomerMapper4.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCustomerMapper4.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + alternativeLine = 22, // Javac wrong error reporting on repeatable annotations JDK-8042710 + message = "Constant and nullValuePropertyMappingStrategy are both defined in @Mapping, " + + "either define a constant or an nullValuePropertyMappingStrategy.") + } + ) + public void testBothConstantAndNvpmsDefined() { + } + + @ProcessorTest + @WithClasses(ErroneousCustomerMapper5.class) + @ExpectedCompilationOutcome( + value = CompilationResult.FAILED, + diagnostics = { + @Diagnostic(type = ErroneousCustomerMapper5.class, + kind = javax.tools.Diagnostic.Kind.ERROR, + line = 20, + alternativeLine = 22, // Javac wrong error reporting on repeatable annotations JDK-8042710 + message = "Ignore and nullValuePropertyMappingStrategy are both defined in @Mapping, " + + "either define ignore or an nullValuePropertyMappingStrategy.") + } + ) + public void testBothIgnoreAndNvpmsDefined() { + } + + private void testConfig(BiConsumer customerMapper) { + + Customer customer = new Customer(); + customer.setAddress( null ); + + CustomerDTO customerDto = new CustomerDTO(); + customerDto.setAddress( new AddressDTO() ); + customerDto.getAddress().setHouseNo( 5 ); + customerDto.setDetails( Arrays.asList( "green hair" ) ); + + customerMapper.accept( customer, customerDto ); + + assertThat( customerDto.getAddress() ).isNotNull(); + assertThat( customerDto.getAddress().getHouseNo() ).isEqualTo( 5 ); + assertThat( customerDto.getDetails() ).isNotNull(); + assertThat( customerDto.getDetails() ).containsExactly( "green hair" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/NvpmsConfig.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/NvpmsConfig.java new file mode 100644 index 0000000000..bf89b1e98f --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/NvpmsConfig.java @@ -0,0 +1,13 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import org.mapstruct.MapperConfig; +import org.mapstruct.NullValuePropertyMappingStrategy; + +@MapperConfig( nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE ) +public interface NvpmsConfig { +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/UserDTO.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/UserDTO.java new file mode 100644 index 0000000000..9dc9af6efb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/UserDTO.java @@ -0,0 +1,30 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping; + +import java.util.List; + +public class UserDTO { + + private HomeDTO homeDTO; + private List details; + + public HomeDTO getHomeDTO() { + return homeDTO; + } + + public void setHomeDTO(HomeDTO homeDTO) { + this.homeDTO = homeDTO; + } + + public List getDetails() { + return details; + } + + public void setDetails(List details) { + this.details = details; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/Bean.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/Bean.java new file mode 100644 index 0000000000..545ddffe8b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/Bean.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +import java.util.Collection; +import java.util.Map; + +public class Bean { + + private String id; + private Collection list; + private Map map; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Collection getList() { + return list; + } + + public void setList(Collection list) { + this.list = list; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanDTO.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanDTO.java new file mode 100644 index 0000000000..9529da8113 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanDTO.java @@ -0,0 +1,40 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +import java.util.Collection; +import java.util.Map; + +public class BeanDTO { + + private String id; + private Collection list; + private Map map; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Collection getList() { + return list; + } + + public void setList(Collection list) { + this.list = list; + } + + public Map getMap() { + return map; + } + + public void setMap(Map map) { + this.map = map; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanDTOWithId.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanDTOWithId.java new file mode 100644 index 0000000000..152a872d82 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanDTOWithId.java @@ -0,0 +1,19 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +public class BeanDTOWithId extends BeanDTO { + + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanMapper.java new file mode 100644 index 0000000000..4d453579ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanMapper.java @@ -0,0 +1,34 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface BeanMapper { + + BeanMapper INSTANCE = Mappers.getMapper( BeanMapper.class ); + + @Mapping(target = "list", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR) + @Mapping(target = "map", nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR) + BeanDTO map(Bean source, @MappingTarget BeanDTO target); + + @Mapping(target = "id", source = "bean.id") + @Mapping(target = "list", source = "bean.list", + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR) + @Mapping(target = "map", source = "bean.map", + nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR) + BeanDTO map(NestedBean source, @MappingTarget BeanDTO target); + + @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR) + BeanDTO mapWithBeanMapping(Bean source, @MappingTarget BeanDTO target); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanMapperWithStrategyOnMapper.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanMapperWithStrategyOnMapper.java new file mode 100644 index 0000000000..0e26b91b5b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/BeanMapperWithStrategyOnMapper.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.CLEAR) +public interface BeanMapperWithStrategyOnMapper { + + BeanMapperWithStrategyOnMapper INSTANCE = Mappers.getMapper( BeanMapperWithStrategyOnMapper.class ); + + BeanDTO map(Bean source, @MappingTarget BeanDTO target); + + @Mapping(target = "id", source = "bean.id") + @Mapping(target = "list", source = "bean.list") + @Mapping(target = "map", source = "bean.map") + BeanDTO map(NestedBean source, @MappingTarget BeanDTO target); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/NestedBean.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/NestedBean.java new file mode 100644 index 0000000000..448645c107 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/NestedBean.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +public class NestedBean { + private Bean bean; + + public Bean getBean() { + return bean; + } + + public void setBean(Bean bean) { + this.bean = bean; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/NullValuePropertyMappingClearTest.java b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/NullValuePropertyMappingClearTest.java new file mode 100644 index 0000000000..20cbcdc2b4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/nullvaluepropertymapping/clear/NullValuePropertyMappingClearTest.java @@ -0,0 +1,116 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.nullvaluepropertymapping.clear; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + Bean.class, + BeanDTO.class, + NestedBean.class, +}) +class NullValuePropertyMappingClearTest { + + @ProcessorTest + @WithClasses(BeanMapper.class) + void generatedMapperMethodsShouldCallClear() { + BeanDTO target = new BeanDTO(); + target.setId( "target" ); + List targetList = new ArrayList<>(); + targetList.add( "a" ); + targetList.add( "b" ); + target.setList( targetList ); + Map targetMap = new HashMap<>(); + targetMap.put( "a", "aValue" ); + target.setMap( targetMap ); + Bean source = new Bean(); + + BeanMapper.INSTANCE.map( source, target ); + assertThat( target.getId() ).isNull(); + assertThat( target.getList() ) + .isSameAs( targetList ) + .isEmpty(); + assertThat( target.getMap() ) + .isSameAs( targetMap ) + .isEmpty(); + + NestedBean nestedBean = new NestedBean(); + nestedBean.setBean( source ); + targetList.add( "a" ); + targetList.add( "b" ); + targetMap.put( "a", "aValue" ); + target.setId( "target" ); + BeanMapper.INSTANCE.map( nestedBean, target ); + assertThat( target.getId() ).isNull(); + assertThat( target.getList() ) + .isSameAs( targetList ) + .isEmpty(); + assertThat( target.getMap() ) + .isSameAs( targetMap ) + .isEmpty(); + + targetList.add( "a" ); + targetList.add( "b" ); + targetMap.put( "a", "aValue" ); + target.setId( "target" ); + BeanMapper.INSTANCE.mapWithBeanMapping( source, target ); + assertThat( target.getId() ).isNull(); + assertThat( target.getList() ) + .isSameAs( targetList ) + .isEmpty(); + assertThat( target.getMap() ) + .isSameAs( targetMap ) + .isEmpty(); + } + + @ProcessorTest + @WithClasses(BeanMapperWithStrategyOnMapper.class) + void generatedMapperWithMappingDefinedInConfigMethodsShouldCallClear() { + BeanDTO target = new BeanDTO(); + target.setId( "target" ); + List targetList = new ArrayList<>(); + targetList.add( "a" ); + targetList.add( "b" ); + target.setList( targetList ); + Map targetMap = new HashMap<>(); + targetMap.put( "a", "aValue" ); + target.setMap( targetMap ); + Bean source = new Bean(); + + BeanMapperWithStrategyOnMapper.INSTANCE.map( source, target ); + assertThat( target.getId() ).isNull(); + assertThat( target.getList() ) + .isSameAs( targetList ) + .isEmpty(); + assertThat( target.getMap() ) + .isSameAs( targetMap ) + .isEmpty(); + + NestedBean nestedBean = new NestedBean(); + nestedBean.setBean( source ); + targetList.add( "a" ); + targetList.add( "b" ); + targetMap.put( "a", "aValue" ); + target.setId( "target" ); + BeanMapperWithStrategyOnMapper.INSTANCE.map( nestedBean, target ); + assertThat( target.getId() ).isNull(); + assertThat( target.getList() ) + .isSameAs( targetList ) + .isEmpty(); + assertThat( target.getMap() ) + .isSameAs( targetMap ) + .isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/oneway/OnewayTest.java b/processor/src/test/java/org/mapstruct/ap/test/oneway/OnewayTest.java index 316c1511fd..f69497f3a3 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/oneway/OnewayTest.java +++ b/processor/src/test/java/org/mapstruct/ap/test/oneway/OnewayTest.java @@ -1,30 +1,15 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at +/* + * Copyright MapStruct Authors. * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.oneway; -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; -import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.WithClasses; -import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; /** * Test for propagation of attribute without setter in source and getter in @@ -33,10 +18,9 @@ * @author Gunnar Morling */ @WithClasses({ Source.class, Target.class, SourceTargetMapper.class }) -@RunWith(AnnotationProcessorTestRunner.class) public class OnewayTest { - @Test + @ProcessorTest @IssueKey("17") public void shouldMapAttributeWithoutSetterInSourceType() { Source source = new Source(); @@ -47,7 +31,7 @@ public void shouldMapAttributeWithoutSetterInSourceType() { assertThat( target.retrieveFoo() ).isEqualTo( Long.valueOf( 42 ) ); } - @Test + @ProcessorTest @IssueKey("41") public void shouldReverseMapAttributeWithoutSetterInTargetType() { Target target = new Target(); @@ -58,7 +42,7 @@ public void shouldReverseMapAttributeWithoutSetterInTargetType() { assertThat( source.retrieveBar() ).isEqualTo( 23 ); } - @Test + @ProcessorTest @IssueKey("104") public void shouldMapMappedAttributeWithoutSetterInSourceType() { Source source = new Source(); diff --git a/processor/src/test/java/org/mapstruct/ap/test/oneway/Source.java b/processor/src/test/java/org/mapstruct/ap/test/oneway/Source.java index 96651cad7f..9a34fe5d81 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/oneway/Source.java +++ b/processor/src/test/java/org/mapstruct/ap/test/oneway/Source.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.oneway; diff --git a/processor/src/test/java/org/mapstruct/ap/test/oneway/SourceTargetMapper.java b/processor/src/test/java/org/mapstruct/ap/test/oneway/SourceTargetMapper.java index 6846bc0a49..e8cf4c5681 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/oneway/SourceTargetMapper.java +++ b/processor/src/test/java/org/mapstruct/ap/test/oneway/SourceTargetMapper.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.oneway; @@ -27,7 +14,7 @@ public interface SourceTargetMapper { SourceTargetMapper INSTANCE = Mappers.getMapper( SourceTargetMapper.class ); - @Mapping(source = "qax", target = "qux") + @Mapping(target = "qux", source = "qax") Target sourceToTarget(Source source); Source targetToSource(Target target); diff --git a/processor/src/test/java/org/mapstruct/ap/test/oneway/Target.java b/processor/src/test/java/org/mapstruct/ap/test/oneway/Target.java index c3e3ca2a38..9514596f03 100644 --- a/processor/src/test/java/org/mapstruct/ap/test/oneway/Target.java +++ b/processor/src/test/java/org/mapstruct/ap/test/oneway/Target.java @@ -1,20 +1,7 @@ -/** - * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) - * and/or other contributors as indicated by the @authors tag. See the - * copyright.txt file in the distribution for a full listing of all - * contributors. +/* + * Copyright MapStruct Authors. * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 */ package org.mapstruct.ap.test.oneway; diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/OptionalBeforeAfterMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/OptionalBeforeAfterMapper.java new file mode 100644 index 0000000000..30dca2cf39 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/OptionalBeforeAfterMapper.java @@ -0,0 +1,76 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.beforeafter; + +import java.util.Optional; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.TargetType; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface OptionalBeforeAfterMapper { + + OptionalBeforeAfterMapper INSTANCE = Mappers.getMapper( OptionalBeforeAfterMapper.class ); + + Target toTarget(Source source); + + @BeforeMapping + default void beforeDeepOptionalSourceWithNoTargetType(Optional source) { + } + + @BeforeMapping + default void beforeDeepOptionalSourceWithNonOptionalTargetType(@TargetType Class targetType, + Optional source) { + } + + @AfterMapping + default void afterDeepOptionalSourceWithNoTarget(Optional source) { + + } + + @AfterMapping + default void afterDeepOptionalSourceWithNonOptionalTarget(@MappingTarget Target.SubType target, + Optional source) { + } + + @AfterMapping + default void afterDeepOptionalSourceWithOptionalTarget(@MappingTarget Optional target, + Optional source) { + } + + @AfterMapping + default void afterDeepNonOptionalSourceOptionalTarget(@MappingTarget Optional target, + Source.SubType source) { + } + + @BeforeMapping + default void beforeShallowOptionalSourceWithNoTargetType(Optional source) { + } + + @BeforeMapping + default void beforeShallowOptionalSourceWithNonOptionalTargetType(@TargetType Class targetType, + Optional source) { + } + + @AfterMapping + default void afterShallowOptionalSourceWithNoTarget(Optional source) { + + } + + @AfterMapping + default void afterShallowOptionalSourceWithNonOptionalTarget(@MappingTarget String target, + Optional source) { + } + + @AfterMapping + default void afterShallowNonOptionalSourceOptionalTarget(@MappingTarget Optional target, String source) { + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/OptionalBeforeAfterTest.java b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/OptionalBeforeAfterTest.java new file mode 100644 index 0000000000..ba1a7b09d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/OptionalBeforeAfterTest.java @@ -0,0 +1,25 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.beforeafter; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +@WithClasses({ + OptionalBeforeAfterMapper.class, Source.class, Target.class +}) +class OptionalBeforeAfterTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + void generatedCode() { + generatedSource.addComparisonToFixtureFor( OptionalBeforeAfterMapper.class ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/Source.java b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/Source.java new file mode 100644 index 0000000000..1284bca7ea --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/Source.java @@ -0,0 +1,87 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.beforeafter; + +import java.util.Objects; +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class Source { + + private final Optional deepOptionalToOptional; + private final Optional deepOptionalToNonOptional; + private final SubType deepNonOptionalToOptional; + + private final Optional shallowOptionalToOptional; + private final Optional shallowOptionalToNonOptional; + private final String shallowNonOptionalToOptional; + + public Source(Optional deepOptionalToOptional, Optional deepOptionalToNonOptional, + SubType deepNonOptionalToOptional, Optional shallowOptionalToOptional, + Optional shallowOptionalToNonOptional, String shallowNonOptionalToOptional) { + this.deepOptionalToOptional = deepOptionalToOptional; + this.deepOptionalToNonOptional = deepOptionalToNonOptional; + this.deepNonOptionalToOptional = deepNonOptionalToOptional; + this.shallowOptionalToOptional = shallowOptionalToOptional; + this.shallowOptionalToNonOptional = shallowOptionalToNonOptional; + this.shallowNonOptionalToOptional = shallowNonOptionalToOptional; + } + + public Optional getDeepOptionalToOptional() { + return deepOptionalToOptional; + } + + public Optional getDeepOptionalToNonOptional() { + return deepOptionalToNonOptional; + } + + public SubType getDeepNonOptionalToOptional() { + return deepNonOptionalToOptional; + } + + public Optional getShallowOptionalToOptional() { + return shallowOptionalToOptional; + } + + public Optional getShallowOptionalToNonOptional() { + return shallowOptionalToNonOptional; + } + + public String getShallowNonOptionalToOptional() { + return shallowNonOptionalToOptional; + } + + public static class SubType { + + private final String value; + + public SubType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SubType subType = (SubType) o; + return Objects.equals( value, subType.value ); + } + + @Override + public int hashCode() { + return Objects.hash( value ); + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/Target.java b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/Target.java new file mode 100644 index 0000000000..592e3338fe --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/beforeafter/Target.java @@ -0,0 +1,86 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.beforeafter; + +import java.util.Objects; +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class Target { + + private final Optional deepOptionalToOptional; + private final SubType deepOptionalToNonOptional; + private final Optional deepNonOptionalToOptional; + + private final Optional shallowOptionalToOptional; + private final String shallowOptionalToNonOptional; + private final Optional shallowNonOptionalToOptional; + + public Target(Optional deepOptionalToOptional, SubType deepOptionalToNonOptional, + Optional deepNonOptionalToOptional, Optional shallowOptionalToOptional, + String shallowOptionalToNonOptional, Optional shallowNonOptionalToOptional) { + this.deepOptionalToOptional = deepOptionalToOptional; + this.deepOptionalToNonOptional = deepOptionalToNonOptional; + this.deepNonOptionalToOptional = deepNonOptionalToOptional; + this.shallowOptionalToOptional = shallowOptionalToOptional; + this.shallowOptionalToNonOptional = shallowOptionalToNonOptional; + this.shallowNonOptionalToOptional = shallowNonOptionalToOptional; + } + + public Optional getDeepOptionalToOptional() { + return deepOptionalToOptional; + } + + public SubType getDeepOptionalToNonOptional() { + return deepOptionalToNonOptional; + } + + public Optional getDeepNonOptionalToOptional() { + return deepNonOptionalToOptional; + } + + public Optional getShallowOptionalToOptional() { + return shallowOptionalToOptional; + } + + public String getShallowOptionalToNonOptional() { + return shallowOptionalToNonOptional; + } + + public Optional getShallowNonOptionalToOptional() { + return shallowNonOptionalToOptional; + } + + public static class SubType { + + private final String value; + + public SubType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + SubType subType = (SubType) o; + return Objects.equals( value, subType.value ); + } + + @Override + public int hashCode() { + return Objects.hash( value ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/builder/OptionalBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/OptionalBuilderTest.java new file mode 100644 index 0000000000..9dd4b01256 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/OptionalBuilderTest.java @@ -0,0 +1,31 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.builder; + +import java.util.Optional; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +class OptionalBuilderTest { + + @ProcessorTest + @WithClasses(SimpleOptionalBuilderMapper.class) + void simpleOptionalBuilder() { + Optional targetOpt = SimpleOptionalBuilderMapper.INSTANCE.map( null ); + assertThat( targetOpt ).isEmpty(); + + targetOpt = SimpleOptionalBuilderMapper.INSTANCE.map( new SimpleOptionalBuilderMapper.Source( "test" ) ); + assertThat( targetOpt ).isNotEmpty(); + SimpleOptionalBuilderMapper.Target target = targetOpt.get(); + assertThat( target.getValue() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/builder/SimpleOptionalBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/SimpleOptionalBuilderMapper.java new file mode 100644 index 0000000000..5f24aa0cae --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/SimpleOptionalBuilderMapper.java @@ -0,0 +1,67 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.builder; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface SimpleOptionalBuilderMapper { + + SimpleOptionalBuilderMapper INSTANCE = Mappers.getMapper( SimpleOptionalBuilderMapper.class ); + + Optional map(Source source); + + class Source { + private final String value; + + public Source(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + } + + class Target { + + private final String value; + + private Target(TargetBuilder builder) { + this.value = builder.value; + } + + public String getValue() { + return value; + } + + public static TargetBuilder builder() { + return new TargetBuilder(); + } + + } + + class TargetBuilder { + + private String value; + + public TargetBuilder value(String value) { + this.value = value; + return this; + } + + public Target build() { + return new Target(this); + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/CrossPackageOptionalBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/CrossPackageOptionalBuilderMapper.java new file mode 100644 index 0000000000..bdff608ddc --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/CrossPackageOptionalBuilderMapper.java @@ -0,0 +1,20 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.builder.crosspackage; + +import java.util.Optional; + +import org.mapstruct.Mapper; +import org.mapstruct.ap.test.optional.builder.crosspackage.dto.PersonTarget; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface CrossPackageOptionalBuilderMapper { + + CrossPackageOptionalBuilderMapper INSTANCE = Mappers.getMapper( CrossPackageOptionalBuilderMapper.class ); + + Optional toTarget(PersonSource source); +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/CrossPackageOptionalBuilderTest.java b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/CrossPackageOptionalBuilderTest.java new file mode 100644 index 0000000000..8919787dfb --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/CrossPackageOptionalBuilderTest.java @@ -0,0 +1,29 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.builder.crosspackage; + +import java.util.Optional; + +import org.mapstruct.ap.test.optional.builder.crosspackage.dto.PersonTarget; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +@IssueKey( "4046" ) +@WithClasses({ CrossPackageOptionalBuilderMapper.class, PersonSource.class, PersonTarget.class }) +class CrossPackageOptionalBuilderTest { + + @ProcessorTest + void shouldUseStaticBuilderMethodForOptionalTargetAcrossPackages() { + PersonSource source = new PersonSource( "John" ); + Optional result = CrossPackageOptionalBuilderMapper.INSTANCE.toTarget( source ); + + assertThat( result ).isPresent(); + assertThat( result.get().getName() ).isEqualTo( "John" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/PersonSource.java b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/PersonSource.java new file mode 100644 index 0000000000..dea0c2f2b8 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/PersonSource.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.builder.crosspackage; + +public class PersonSource { + private final String name; + + public PersonSource(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/dto/PersonTarget.java b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/dto/PersonTarget.java new file mode 100644 index 0000000000..6fb5ab770b --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/builder/crosspackage/dto/PersonTarget.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.builder.crosspackage.dto; + +public class PersonTarget { + + private final String name; + + private PersonTarget(PersonTargetBuilder builder) { + this.name = builder.name; + } + + public String getName() { + return name; + } + + public static PersonTargetBuilder builder() { + return new PersonTargetBuilder(); + } + + public static class PersonTargetBuilder { + + private String name; + + PersonTargetBuilder() { } + + public PersonTargetBuilder name(String name) { + this.name = name; + return this; + } + + public PersonTarget build() { + return new PersonTarget( this ); + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/custom/CustomOptionalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/custom/CustomOptionalMapper.java new file mode 100644 index 0000000000..a6f8c155d4 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/custom/CustomOptionalMapper.java @@ -0,0 +1,63 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.custom; + +import java.util.Optional; + +import org.mapstruct.Condition; +import org.mapstruct.Mapper; +import org.mapstruct.MappingTarget; +import org.mapstruct.NullValuePropertyMappingStrategy; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE) +@SuppressWarnings("OptionalAssignedToNull") +public interface CustomOptionalMapper { + + CustomOptionalMapper INSTANCE = Mappers.getMapper( CustomOptionalMapper.class ); + + Target map(Source source); + + void update(@MappingTarget Target target, Source source); + + @Condition + default boolean isPresent(Optional optional) { + return optional != null; + } + + default E unwrapFromOptional(Optional optional) { + return optional == null + ? null + : optional.orElse( null ); + } + + class Target { + private String value = "initial"; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + } + + class Source { + private final Optional value; + + public Source(Optional value) { + this.value = value; + } + + public Optional getValue() { + return value; + } + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/custom/CustomOptionalTest.java b/processor/src/test/java/org/mapstruct/ap/test/optional/custom/CustomOptionalTest.java new file mode 100644 index 0000000000..51991ac478 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/custom/CustomOptionalTest.java @@ -0,0 +1,60 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.custom; + +import java.util.Optional; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses(CustomOptionalMapper.class) +class CustomOptionalTest { + + @ProcessorTest + void shouldUseCustomMethodsWhenMapping() { + CustomOptionalMapper.Target target = CustomOptionalMapper.INSTANCE. + map( new CustomOptionalMapper.Source( null ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "initial" ); + + target = CustomOptionalMapper.INSTANCE.map( new CustomOptionalMapper.Source( Optional.empty() ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + + target = CustomOptionalMapper.INSTANCE.map( new CustomOptionalMapper.Source( Optional.of( "test" ) ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "test" ); + } + + @ProcessorTest + void shouldUseCustomMethodsWhenUpdating() { + CustomOptionalMapper.Target target = new CustomOptionalMapper.Target(); + + CustomOptionalMapper.INSTANCE.update( target, new CustomOptionalMapper.Source( null ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "initial" ); + + CustomOptionalMapper.INSTANCE.update( target, new CustomOptionalMapper.Source( Optional.empty() ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isNull(); + + target = new CustomOptionalMapper.Target(); + CustomOptionalMapper.INSTANCE.update( target, new CustomOptionalMapper.Source( Optional.of( "test" ) ) ); + + assertThat( target ).isNotNull(); + assertThat( target.getValue() ).isEqualTo( "test" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/OptionalDifferentTypesMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/OptionalDifferentTypesMapper.java new file mode 100644 index 0000000000..5a276b4745 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/OptionalDifferentTypesMapper.java @@ -0,0 +1,18 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.differenttypes; + +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface OptionalDifferentTypesMapper { + + OptionalDifferentTypesMapper INSTANCE = Mappers.getMapper( OptionalDifferentTypesMapper.class ); + + Target toTarget(Source source); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/OptionalDifferentTypesTest.java b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/OptionalDifferentTypesTest.java new file mode 100644 index 0000000000..74ab85e174 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/OptionalDifferentTypesTest.java @@ -0,0 +1,204 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.differenttypes; + +import java.util.Optional; + +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.GeneratedSource; + +import static org.assertj.core.api.Assertions.assertThat; + +@WithClasses({ + OptionalDifferentTypesMapper.class, Source.class, Target.class +}) +class OptionalDifferentTypesTest { + + @RegisterExtension + final GeneratedSource generatedSource = new GeneratedSource(); + + @ProcessorTest + void generatedCode() { + generatedSource.addComparisonToFixtureFor( OptionalDifferentTypesMapper.class ); + } + + @ProcessorTest + void constructorOptionalToOptionalWhenPresent() { + Source source = new Source( Optional.of( new Source.SubType( "some value" ) ), Optional.empty(), null ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getConstructorOptionalToOptional() ) + .hasValueSatisfying( subType -> + assertThat( subType.getValue() ).isEqualTo( "some value" ) ); + } + + @ProcessorTest + void constructorOptionalToOptionalWhenEmpty() { + Source source = new Source(); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getConstructorOptionalToOptional() ).isEmpty(); + } + + @ProcessorTest + void constructorOptionalToNonOptionalWhenPresent() { + Source source = new Source( Optional.empty(), Optional.of( new Source.SubType( "some value" ) ), null ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + Target.SubType subType = target.getConstructorOptionalToNonOptional(); + assertThat( subType ).isNotNull(); + assertThat( subType.getValue() ).isEqualTo( "some value" ); + } + + @ProcessorTest + void constructorOptionalToNonOptionalWhenEmpty() { + Source source = new Source(); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getConstructorOptionalToNonOptional() ).isNull(); + } + + @ProcessorTest + void constructorNonOptionalToOptionalWhenNotNull() { + Source source = new Source( Optional.empty(), Optional.empty(), new Source.SubType( "some value" ) ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getConstructorNonOptionalToOptional() ) + .hasValueSatisfying( subType -> + assertThat( subType.getValue() ).isEqualTo( "some value" ) ); + } + + @ProcessorTest + void constructorNonOptionalToOptionalWhenNull() { + Source source = new Source(); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getConstructorNonOptionalToOptional() ).isEmpty(); + } + + @ProcessorTest + void optionalToOptionalWhenPresent() { + Source source = new Source(); + source.setOptionalToOptional( Optional.of( new Source.SubType( "some value" ) ) ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getOptionalToOptional() ) + .hasValueSatisfying( subType -> + assertThat( subType.getValue() ).isEqualTo( "some value" ) ); + } + + @ProcessorTest + void optionalToOptionalWhenEmpty() { + Source source = new Source(); + source.setOptionalToOptional( Optional.empty() ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getOptionalToOptional() ).isEmpty(); + } + + @ProcessorTest + void optionalToNonOptionalWhenPresent() { + Source source = new Source(); + source.setOptionalToNonOptional( Optional.of( new Source.SubType( "some value" ) ) ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + Target.SubType subType = target.getOptionalToNonOptional(); + assertThat( subType ).isNotNull(); + assertThat( subType.getValue() ).isEqualTo( "some value" ); + } + + @ProcessorTest + void optionalToNonOptionalWhenEmpty() { + Source source = new Source(); + source.setOptionalToNonOptional( Optional.empty() ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getOptionalToNonOptional() ).isNull(); + } + + @ProcessorTest + void nonOptionalToOptionalWhenNotNull() { + Source source = new Source(); + source.setNonOptionalToOptional( new Source.SubType( "some value" ) ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getNonOptionalToOptional() ) + .hasValueSatisfying( subType -> + assertThat( subType.getValue() ).isEqualTo( "some value" ) ); + } + + @ProcessorTest + void nonOptionalToOptionalWhenNull() { + Source source = new Source(); + source.setNonOptionalToOptional( null ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.getNonOptionalToOptional() ).isEmpty(); + } + + @ProcessorTest + void publicOptionalToOptionalWhenPresent() { + Source source = new Source(); + source.publicOptionalToOptional = Optional.of( new Source.SubType( "some value" ) ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.publicOptionalToOptional ) + .hasValueSatisfying( subType -> + assertThat( subType.getValue() ).isEqualTo( "some value" ) ); + } + + @ProcessorTest + void publicOptionalToOptionalWhenEmpty() { + Source source = new Source(); + source.publicOptionalToOptional = Optional.empty(); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.publicOptionalToOptional ).isEmpty(); + } + + @ProcessorTest + void publicOptionalToNonOptionalWhenPresent() { + Source source = new Source(); + source.publicOptionalToNonOptional = Optional.of( new Source.SubType( "some value" ) ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + Target.SubType subType = target.publicOptionalToNonOptional; + assertThat( subType ).isNotNull(); + assertThat( subType.getValue() ).isEqualTo( "some value" ); + } + + @ProcessorTest + void publicOptionalToNonOptionalWhenEmpty() { + Source source = new Source(); + source.publicOptionalToNonOptional = Optional.empty(); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.publicOptionalToNonOptional ).isNull(); + } + + @ProcessorTest + void publicNonOptionalToOptionalWhenNotNull() { + Source source = new Source(); + source.publicNonOptionalToOptional = new Source.SubType( "some value" ); + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.publicNonOptionalToOptional ) + .hasValueSatisfying( subType -> + assertThat( subType.getValue() ).isEqualTo( "some value" ) ); + } + + @ProcessorTest + void publicNonOptionalToOptionalWhenNull() { + Source source = new Source(); + source.publicNonOptionalToOptional = null; + + Target target = OptionalDifferentTypesMapper.INSTANCE.toTarget( source ); + assertThat( target.publicNonOptionalToOptional ).isEmpty(); + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/Source.java b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/Source.java new file mode 100644 index 0000000000..0c0648000a --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/Source.java @@ -0,0 +1,89 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.differenttypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class Source { + + private final Optional constructorOptionalToOptional; + private final Optional constructorOptionalToNonOptional; + private final SubType constructorNonOptionalToOptional; + + private Optional optionalToOptional = Optional.empty(); + private Optional optionalToNonOptional = Optional.empty(); + private SubType nonOptionalToOptional; + + @SuppressWarnings( "VisibilityModifier" ) + public Optional publicOptionalToOptional = Optional.empty(); + @SuppressWarnings( "VisibilityModifier" ) + public Optional publicOptionalToNonOptional = Optional.empty(); + @SuppressWarnings( "VisibilityModifier" ) + public SubType publicNonOptionalToOptional; + + public Source() { + this( Optional.empty(), Optional.empty(), null ); + } + + public Source(Optional constructorOptionalToOptional, Optional constructorOptionalToNonOptional, + SubType constructorNonOptionalToOptional) { + this.constructorOptionalToOptional = constructorOptionalToOptional; + this.constructorOptionalToNonOptional = constructorOptionalToNonOptional; + this.constructorNonOptionalToOptional = constructorNonOptionalToOptional; + } + + public Optional getConstructorOptionalToOptional() { + return constructorOptionalToOptional; + } + + public Optional getConstructorOptionalToNonOptional() { + return constructorOptionalToNonOptional; + } + + public SubType getConstructorNonOptionalToOptional() { + return constructorNonOptionalToOptional; + } + + public Optional getOptionalToOptional() { + return optionalToOptional; + } + + public void setOptionalToOptional(Optional optionalToOptional) { + this.optionalToOptional = optionalToOptional; + } + + public Optional getOptionalToNonOptional() { + return optionalToNonOptional; + } + + public void setOptionalToNonOptional(Optional optionalToNonOptional) { + this.optionalToNonOptional = optionalToNonOptional; + } + + public SubType getNonOptionalToOptional() { + return nonOptionalToOptional; + } + + public void setNonOptionalToOptional(SubType nonOptionalToOptional) { + this.nonOptionalToOptional = nonOptionalToOptional; + } + + public static class SubType { + + private final String value; + + public SubType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/Target.java b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/Target.java new file mode 100644 index 0000000000..4f2b21c8a7 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/differenttypes/Target.java @@ -0,0 +1,84 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.differenttypes; + +import java.util.Optional; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class Target { + + private final Optional constructorOptionalToOptional; + private final SubType constructorOptionalToNonOptional; + private final Optional constructorNonOptionalToOptional; + + private Optional optionalToOptional = Optional.of( new SubType( "initial" ) ); + private SubType optionalToNonOptional; + private Optional nonOptionalToOptional = Optional.of( new SubType( "initial" ) ); + + @SuppressWarnings( "VisibilityModifier" ) + public Optional publicOptionalToOptional = Optional.of( new SubType( "initial" ) ); + @SuppressWarnings( "VisibilityModifier" ) + public SubType publicOptionalToNonOptional; + @SuppressWarnings( "VisibilityModifier" ) + public Optional publicNonOptionalToOptional = Optional.of( new SubType( "initial" ) ); + + public Target(Optional constructorOptionalToOptional, SubType constructorOptionalToNonOptional, + Optional constructorNonOptionalToOptional) { + this.constructorOptionalToOptional = constructorOptionalToOptional; + this.constructorOptionalToNonOptional = constructorOptionalToNonOptional; + this.constructorNonOptionalToOptional = constructorNonOptionalToOptional; + } + + public Optional getConstructorOptionalToOptional() { + return constructorOptionalToOptional; + } + + public SubType getConstructorOptionalToNonOptional() { + return constructorOptionalToNonOptional; + } + + public Optional getConstructorNonOptionalToOptional() { + return constructorNonOptionalToOptional; + } + + public Optional getOptionalToOptional() { + return optionalToOptional; + } + + public void setOptionalToOptional(Optional optionalToOptional) { + this.optionalToOptional = optionalToOptional; + } + + public SubType getOptionalToNonOptional() { + return optionalToNonOptional; + } + + public void setOptionalToNonOptional(SubType optionalToNonOptional) { + this.optionalToNonOptional = optionalToNonOptional; + } + + public Optional getNonOptionalToOptional() { + return nonOptionalToOptional; + } + + public void setNonOptionalToOptional(Optional nonOptionalToOptional) { + this.nonOptionalToOptional = nonOptionalToOptional; + } + + public static class SubType { + + private final String value; + + public SubType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/MappingContext.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/MappingContext.java new file mode 100644 index 0000000000..3624efb00e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/MappingContext.java @@ -0,0 +1,108 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.mapstruct.AfterMapping; +import org.mapstruct.BeforeMapping; +import org.mapstruct.MappingTarget; +import org.mapstruct.TargetType; + +/** + * @author Filip Hrisafov + */ +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class MappingContext { + + private final List invokedMethods = new ArrayList<>(); + + @BeforeMapping + public void beforeWithoutParameters() { + invokedMethods.add( "beforeWithoutParameters" ); + } + + @BeforeMapping + public void beforeWithOptionalSource(Optional source) { + invokedMethods.add( "beforeWithOptionalSource" ); + } + + @BeforeMapping + public void beforeWithSource(Source source) { + invokedMethods.add( "beforeWithSource" ); + } + + @BeforeMapping + public void beforeWithTargetType(@TargetType Class targetClass) { + invokedMethods.add( "beforeWithTargetType" ); + } + + @BeforeMapping + public void beforeWithBuilderTargetType(@TargetType Class targetBuilderClass) { + invokedMethods.add( "beforeWithBuilderTargetType" ); + } + + @BeforeMapping + public void beforeWithOptionalTarget(@MappingTarget Optional target) { + invokedMethods.add( "beforeWithOptionalTarget" ); + } + + @BeforeMapping + public void beforeWithTarget(@MappingTarget Target target) { + invokedMethods.add( "beforeWithTarget" ); + } + + @BeforeMapping + public void beforeWithTargetBuilder(@MappingTarget Target.Builder target) { + invokedMethods.add( "beforeWithTargetBuilder" ); + } + + @AfterMapping + public void afterWithoutParameters() { + invokedMethods.add( "afterWithoutParameters" ); + } + + @AfterMapping + public void afterWithOptionalSource(Optional source) { + invokedMethods.add( "afterWithOptionalSource" ); + } + + @AfterMapping + public void afterWithSource(Source source) { + invokedMethods.add( "afterWithSource" ); + } + + @AfterMapping + public void afterWithTargetType(@TargetType Class targetClass) { + invokedMethods.add( "afterWithTargetType" ); + } + + @AfterMapping + public void afterWithBuilderTargetType(@TargetType Class targetClass) { + invokedMethods.add( "afterWithBuilderTargetType" ); + } + + @AfterMapping + public void afterWithTarget(@MappingTarget Target target) { + invokedMethods.add( "afterWithTarget" ); + } + + @AfterMapping + public void afterWithTargetBuilder(@MappingTarget Target.Builder target) { + invokedMethods.add( "afterWithTargetBuilder" ); + } + + @AfterMapping + public void afterWithOptionalTarget(@MappingTarget Optional target) { + invokedMethods.add( "afterWithOptionalTarget" ); + } + + public List getInvokedMethods() { + return invokedMethods; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalLifecycleTest.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalLifecycleTest.java new file mode 100644 index 0000000000..c80dfcb6b6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalLifecycleTest.java @@ -0,0 +1,165 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +import java.util.Optional; + +import org.mapstruct.ap.testutil.ProcessorTest; +import org.mapstruct.ap.testutil.WithClasses; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * @author Filip Hrisafov + */ +@WithClasses({ + MappingContext.class, + Source.class, + Target.class, +}) +public class OptionalLifecycleTest { + + @ProcessorTest + @WithClasses(OptionalToOptionalMapper.class) + void optionalToOptional() { + MappingContext context = new MappingContext(); + + OptionalToOptionalMapper.INSTANCE.map( Optional.empty(), context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType" + ); + + context = new MappingContext(); + OptionalToOptionalMapper.INSTANCE.map( Optional.of( new Source() ), context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType", + "beforeWithTarget", + "afterWithoutParameters", + "afterWithOptionalSource", + "afterWithTargetType", + "afterWithTarget", + "afterWithOptionalTarget" + ); + } + + @ProcessorTest + @WithClasses(OptionalToOptionalWithBuilderMapper.class) + void optionalToOptionalWithBuilder() { + MappingContext context = new MappingContext(); + + OptionalToOptionalWithBuilderMapper.INSTANCE.map( Optional.empty(), context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType", + "beforeWithBuilderTargetType" + ); + + context = new MappingContext(); + OptionalToOptionalWithBuilderMapper.INSTANCE.map( Optional.of( new Source() ), context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType", + "beforeWithBuilderTargetType", + "beforeWithTargetBuilder", + "afterWithoutParameters", + "afterWithOptionalSource", + "afterWithTargetType", + "afterWithBuilderTargetType", + "afterWithTarget", + "afterWithTargetBuilder", + "afterWithOptionalTarget" + ); + } + + @ProcessorTest + @WithClasses(OptionalToTypeMapper.class) + void optionalToType() { + MappingContext context = new MappingContext(); + + OptionalToTypeMapper.INSTANCE.map( Optional.empty(), context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType" + ); + + context = new MappingContext(); + OptionalToTypeMapper.INSTANCE.map( Optional.of( new Source() ), context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType", + "beforeWithTarget", + "afterWithoutParameters", + "afterWithOptionalSource", + "afterWithTargetType", + "afterWithTarget" + ); + } + + @ProcessorTest + @WithClasses(OptionalToTypeMultiSourceMapper.class) + void optionalToTypeMultiSource() { + MappingContext context = new MappingContext(); + + OptionalToTypeMultiSourceMapper.INSTANCE.map( Optional.empty(), null, context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType" + ); + + context = new MappingContext(); + OptionalToTypeMultiSourceMapper.INSTANCE.map( Optional.of( new Source() ), null, context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType", + "beforeWithTarget", + "afterWithoutParameters", + "afterWithOptionalSource", + "afterWithTargetType", + "afterWithTarget" + ); + + context = new MappingContext(); + OptionalToTypeMultiSourceMapper.INSTANCE.map( Optional.empty(), "Test", context ); + + assertThat( context.getInvokedMethods() ) + .containsExactlyInAnyOrder( + "beforeWithoutParameters", + "beforeWithOptionalSource", + "beforeWithTargetType", + "beforeWithTarget", + "afterWithoutParameters", + "afterWithOptionalSource", + "afterWithTargetType", + "afterWithTarget" + ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToOptionalMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToOptionalMapper.java new file mode 100644 index 0000000000..d7c5d08173 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToOptionalMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +import java.util.Optional; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Builder; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface OptionalToOptionalMapper { + + OptionalToOptionalMapper INSTANCE = Mappers.getMapper( OptionalToOptionalMapper.class ); + + @BeanMapping(builder = @Builder(disableBuilder = true)) + Optional map(Optional source, @Context MappingContext context); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToOptionalWithBuilderMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToOptionalWithBuilderMapper.java new file mode 100644 index 0000000000..8cfab7fd00 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToOptionalWithBuilderMapper.java @@ -0,0 +1,24 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +import java.util.Optional; + +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface OptionalToOptionalWithBuilderMapper { + + OptionalToOptionalWithBuilderMapper INSTANCE = Mappers.getMapper( OptionalToOptionalWithBuilderMapper.class ); + + Optional map(Optional source, @Context MappingContext context); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToTypeMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToTypeMapper.java new file mode 100644 index 0000000000..6a6f3e096e --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToTypeMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +import java.util.Optional; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Builder; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface OptionalToTypeMapper { + + OptionalToTypeMapper INSTANCE = Mappers.getMapper( OptionalToTypeMapper.class ); + + @BeanMapping(builder = @Builder(disableBuilder = true)) + Target map(Optional source, @Context MappingContext context); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToTypeMultiSourceMapper.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToTypeMultiSourceMapper.java new file mode 100644 index 0000000000..d672f2ec05 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/OptionalToTypeMultiSourceMapper.java @@ -0,0 +1,27 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +import java.util.Optional; + +import org.mapstruct.BeanMapping; +import org.mapstruct.Builder; +import org.mapstruct.Context; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface OptionalToTypeMultiSourceMapper { + + OptionalToTypeMultiSourceMapper INSTANCE = Mappers.getMapper( OptionalToTypeMultiSourceMapper.class ); + + @BeanMapping(builder = @Builder(disableBuilder = true)) + Target map(Optional source, String otherValue, @Context MappingContext context); + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/Source.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/Source.java new file mode 100644 index 0000000000..c7005c6ca6 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/Source.java @@ -0,0 +1,21 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +/** + * @author Filip Hrisafov + */ +public class Source { + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/Target.java b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/Target.java new file mode 100644 index 0000000000..d5f68a1844 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/lifecycle/Target.java @@ -0,0 +1,39 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.lifecycle; + +/** + * @author Filip Hrisafov + */ +public class Target { + + private String value; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public static class Builder { + + private String value; + + public Builder value(String value) { + this.value = value; + return this; + } + + public Target build() { + Target target = new Target(); + target.setValue( value ); + return target; + } + } + +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/optional/nested/Artist.java b/processor/src/test/java/org/mapstruct/ap/test/optional/nested/Artist.java new file mode 100644 index 0000000000..e6ce6faa65 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/optional/nested/Artist.java @@ -0,0 +1,81 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.optional.nested; + +import java.util.Optional; + +/** + * @author Filip Hrisafov + */ +public class Artist { + private final String name; + private final Label label; + + public Artist(String name, Label label) { + this.name = name; + this.label = label; + } + + public boolean hasName() { + return name != null; + } + + public String getName() { + return name; + } + + public boolean hasLabel() { + return label != null; + } + + public Optional